9

C 标准为什么以及在哪里允许编译此代码?它在哪里有用?

struct foo {
  int : 12;
};
4

3 回答 3

6

那将在 §6.7.2.1结构和联合说明符中

12) 没有声明符但只有冒号和宽度的位域声明表示未命名的位域。126

脚注解释了为什么存在这样的事情:

126未命名的位域结构成员可用于填充以符合外部强加的布局。

话虽如此,标准的同一部分(第 8 段)还指出:

如果 struct-declaration-list 不包含任何命名成员,无论是直接还是通过匿名结构或匿名联合,则行为未定义。

但是一些编译器(至少是 GCC 和 clang)允许这个作为扩展。

如果这是结构中唯一的位域,则使用会受到限制,但并非不可能像ouah说明的那样使用。

该标准继续以另一个“奇怪”:

作为一种特殊情况,宽度为 0 的位域结构成员表示不会将进一步的位域打包到放置前一个位域(如果有的话)的单元中。

于 2013-10-04T21:38:00.577 回答
6

该程序调用未定义的行为。

C 说:

(C99,6.7.2.1p7)“[...] 如果 struct-declaration-list 不包含命名成员,则行为未定义。”

现在一些编译器接受它作为扩展。这怎么可能有用?

例如对于 Linux 内核著名的BUILD_BUG_ON_ZERO宏:

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))

要查看此宏的作用,您可以查看此处

于 2013-10-04T21:44:29.320 回答
3

好吧,根据语言规范,如果您的程序包含没有命名成员的结构类型,则行为未定义。(对于为什么它没有被官方认定为违反约束的问题,我没有立即回答。)在 6.7.2.1/7 中有说明

struct-declaration-list 是结构或联合成员的一系列声明。如果 struct-declaration-list 不包含命名成员,则行为未定义。

除此之外,这样的声明并不是真正“有用”,因为它产生的唯一东西是未定义的行为。

于 2013-10-04T21:41:00.013 回答