没有类型说明符的类型限定符

时间:2016-11-24 03:49:04

标签: c

在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

1 个答案:

答案 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也可以编译它们。

另请注意,该示例标有“模糊结构”。任何人实际上都要编写像生产这样的代码,应该......避开它们,直到他们悔改他们的邪恶方式。