在C中,我应该被允许使用指向不完整类型数组的指针吗?

not*_*ser 6 c arrays pointers pointer-arithmetic incomplete-type

IAR Embedded C编译器对此很满意,我认为它是正确的C代码:

struct incomplete;
typedef struct incomplete (*why_not)[2];
struct incomplete {struct incomplete *known_to_work;} array[2];
why_not ok = &array;
Run Code Online (Sandbox Code Playgroud)

但是,gcc和clang choke对定义why_not:

incomplete.c:2:29: error: array type has incomplete element type ‘struct incomplete’
 typedef struct incomplete (*why_not)[2];
                             ^
Run Code Online (Sandbox Code Playgroud)

从技术上讲,没有理由拒绝"指向不完整数组的指针"的定义.毕竟,只有在取消引用这样的变量或执行某些指针算术时才需要结构定义.

我渴望在可能的情况下隐藏结构定义.

C标准对此有何看法?

M.M*_*M.M 7

代码使用数组声明符,其中元素类型不完整.根据6.7.6.2/1 数组声明符,这是ISO C中的约束违规:

约束

除了可选的类型限定符和关键字static之外,[]可以分隔表达式或*.如果它们分隔表达式(指定数组的大小),则表达式应具有整数类型.如果表达式是常量表达式,则其值应大于零.元素类型不应是不完整或函数类型.


眠りネ*_*ネロク 6

以下声明

typedef struct incomplete (*why_not)[2];
Run Code Online (Sandbox Code Playgroud)

是指向两个数组的指针struct incomplete.编译器还不知道它的大小struct incomplete,因为它尚未定义.

但是,以下内容将起作用:

typedef struct incomplete *why_not[2];
Run Code Online (Sandbox Code Playgroud)

即:一个指针数组struct incomplete.编译器确实知道指向不完整类型的指针的大小(即:它只是存储地址所需的大小).


编辑:

编译器不需要知道struct incomplete任何一种情况下的大小(只要没有指针算术发生),因为两个声明都只是声明指针.

  • 编译器也知道指向不完整类型数组的指针的大小,它也只是一个地址。正如我所指出的,至少有一个编译器确实接受了这一点。问题是,标准(C99 或 C11)说什么? (2认同)