typedef声明中的typedef-name是否可选?

时间:2011-06-19 00:56:47

标签: c++ c typedef

当我在g ++ - 4.2中看到以下代码编译没有错误或警告时,我感到非常惊讶:

typedef enum test { one };

我的假设是,如果您使用typedef关键字,则需要额外的标识符,如:

typedef enum test { one } test;

如前所述,g ++ - 4.2在没有警告的情况下接受它。 Clang ++ 3.0警告“警告:typedef需要名称”,类似的Comeau警告“警告:声明需要typedef名称”,g ++ - 4.6通知:“警告:'typedef'在此声明中被忽略“。

我无法确定标准中允许的位置,并且我发现两个编译器警告它是必需有点令人困惑,如果不是错误的话typedef-name是必需但不存在?

更新:我在C中使用相同的编译器进行了检查。 Clang和comeau产生相同的输出,gcc发出警告:“警告:空声明中无用的存储类说明符”,这似乎更令人困惑。

更新:我已检查过删除枚举的名称,结果是一样的:

typedef enum { one };

与命名结构类似:

typedef struct named { int x };

但是没有一个未命名的结构,在这种情况下,代码在g ++(4.2 / 4.6)中被拒绝“错误:在typedef-declaration 中缺少类型名称”,gcc(4.2 / 4.6) )发出警告:“警告:未命名的struct / union,不定义实例”,clang ++“警告:声明不声明任何内容”,来自“错误:声明需要typedef名称

3 个答案:

答案 0 :(得分:42)

答案 1 :(得分:3)

我唯一能找到的是C ++ 03标准§7.1.3 [dcl.typedef] p1中的以下内容:

  

的typedef名:

     
      
  • 标识符
  •   
     

使用typedef说明符声明的名称变为 typedef-name

请注意标识符后缺少 opt ,这至少表明我需要标识符对于 typedef-name 。奇怪的是,所有经过测试的编译器(默默地)接受这个。


编辑:在@ Jonathan的回答之后,我发现以下标准与上述相同:

  

DECL说明符

     
      
  • 存储类说明符
  •   
  • 类型说明符
  •   
  • 功能说明符
  •   
  • friend
  •   
  • typedef
  •   

可以看出,它为typedef提供了一个额外的案例,存储类说明符上的列表证实了这一点:

  

存储类说明符:

     
      
  • auto
  •   
  • register
  •   
  • static
  •   
  • extern
  •   
  • mutable
  •   

所以,在C ++案例中,我们和以前一样无能为力。

答案 2 :(得分:0)

对我而言,它看起来真的像C与C ++的区别。 C ++隐式地为它们的标签键入结构和联合;所以添加typedef是多余的,但不是错误。我不知道这是否适用于枚举。

接下来要做的是查看这些声明后允许的变量定义。

enum test etest;
test etest2;
struct named snamed;
named snamed2;