在ISO / IEC 9899:1999中,在§6.7.7类型定义中,第3个示例(边框上标记的第6个段落)不正确。示例中的解释是这样的(参见底部的代码):
前两个位字段声明的不同之处在于unsigned是a 类型说明符(强制
t
为结构成员的名称), 而const
是类型限定符( 修改t
仍然可以看作typedef名称 )。
它声明声明const t:5
将使类型名称t
的先前定义保持不变。如果我们使用gcc测试它,我们会看到我们可以改变这样的变量,所以gcc忽略const t
。使用clang进行编译也会发生同样的情况。
我理解存在通过类型限定符定义/声明的变量而没有类型说明符是可能的,这与我认为限定符只是保持类型说明符的节点的属性等相反。
C99中的歧义在哪里?
typedef signed int t;
typedef int plain;
struct tag {
unsigned t:4;
const t:5;
plain r:5;
};
int
main()
{
t x;
x = 10;
return 0;
}
另一方面,下一个函数也会编译:
int
main()
{
struct tag x = {.t = 3};
x.t = 4;
return 0;
}
REMARK :
我使用了clang和gcc。
文献:
第138页,本版本的§6.7.8
ISO / IEC 9899:201x委员会草案 - 2011年4月12日N1570
或
本版的第124页,第6.7.7节
ISO / IEC 9899:TC3委员会草案 - 2007年9月7日WG14 / N1256
答案 0 :(得分:0)
示例的完整示例(来自ISO / IEC 9899:2011)是:
示例3以下模糊结构
typedef signed int t; typedef int plain; struct tag { unsigned t:4; const t:5; plain r:5; };
声明类型为
在内部范围内t
的typedef名称signed int
,类型为plain
的typedef名称int
和结构 有三个位字段成员,一个名为t
,包含[0,15]范围内的值,一个未命名的const限定值 位域(如果可以访问)将包含范围[-15,+ 15]或中的值 [-16,+ 15],以及一个名为r
的名称,其中包含[0,31],[ - 15,+ 15]或[-16,+ 15]范围之一的值。 (范围的选择是实现定义的。)前两个位字段声明的不同之处在于unsigned
是一个类型说明符(强制t
为结构成员的名称),而const
是一个 type qualifier(修改t
,它仍然可以作为typedef名称显示)。如果遵循这些声明t f(t (t)); long t;
然后声明一个函数
f
,其类型为''函数,返回signed int
一个未命名的参数 带有指向函数的类型指针返回signed int
,其中一个未命名的参数类型为signed int
'',标识符t
的类型为long int
。
请注意,const t:5;
标识的字段是匿名的,因此无法访问(标准中提及'如果可以访问'评论,以及声明它是& #39;未命名的const-qualified bit-field')。名为t
的字段不是const限定的;它可以被修改。
const
字段是结构struct tag
的一部分,不会影响该结构类型之外的任何内容。
你的示例程序都应该编译 - GCC和Clang也可以编译它们。
另请注意,该示例标有“模糊结构”。任何人实际上都要编写像生产这样的代码,应该......避开它们,直到他们悔改他们的邪恶方式。