指向不完整类型的数据成员

Pointer to data member of incomplete type

本文关键字:类型 数据成员      更新时间:2023-10-16

以下代码在C 中定义明确吗?(*)

我很难弄清楚在标准中可以看哪里,而搜索网络也没有变成任何具体的东西。

struct S;
struct T {
    constexpr T() = default;
    bool S::* a = nullptr;
    int b       = 42;
};
const T t{};
// Test. Compiled using: cl /W4 /WX /FAs filename.cpp
#include <stdlib.h>
int main() {
    if (t.b != 42) abort();
}

我要问的原因是因为它使用gcc和clang(x86/x86_64)的较新版本起作用(或似乎是),但是Visual Studio 2015更新2和更新3 RC。P>

在报告错误之前,我想确保我不依赖不确定的行为或不搜索正确的条款。

我还尝试了本文中提到的/vmg/vmb

(*):我主要关心C 14及以后,但我认为答案不应适用于C 11。
(**):如果代码定义良好,则看起来像是一个代码错误,它不是指针分配室。将struct S更改为struct S{}似乎使代码"工作"。

您的代码定义很好:

N4594 3.2/5

[...] 类型T类必须完成,如果

  • (5.1) 定义了T型的对象(3.1)或
  • (5.2) 声明T型的非静态类数据成员(9.2)或
  • (5.3) t用作新表达(5.3.4)或
  • 中的对象类型或数组元素类型
  • (5.4) 将LVALUE转换到glvalue,指的是T型(4.1)或
  • 的对象
  • (5.5) 表达式被转换为T型T型(第4、5.2.3、5.2.7、5.2.9、5.4)或
  • (5.6) 不是零指针常数的表达式,并且具有CV void*以外的其他类型,被转换为 使用标准转换(第4条),dynamic_cast(5.2.7)或一个 static_cast(5.2.9)或
  • (5.7) 类成员访问操作员被应用于T型(5.2.5)或
  • 的表达式
  • (5.8) TypeID操作员(5.2.8)或尺寸运算符(5.3.3)应用于T型操作数或
  • (5.9) 定义具有返回类型或参数类型的函数(3.1)或称为(5.2.2)或
  • (5.10) 定义了具有T型基类的类(第10条)或
  • (5.11) T型的LVALUE分配给(5.18)或
  • (5.12) T型是对准表达式(5.3.6)或
  • 的主题
  • (5.13) 异常 - 陈述具有T型,引用t或指向T(15.3)。

他们都没有说T需要完成才能声明T的指针到会员。