为什么这个程序在C11中编译好但在C99中没编译?

时间:2015-10-21 14:16:44

标签: c struct typedef c99 c11

考虑以下计划:(参见现场演示here)。

#include <stdio.h>
struct Test
{
    int a;
};
typedef struct Test t;
typedef struct Test t;
int main()
{
    t T={9};
    printf("%d",T.a);
}

程序在C11编译器中编译良好,但在C99编译器中编译失败。为什么?是什么原因? 我的编译器gcc 4.8.1给出了以下警告:

[Warning] redefinition of typedef 't' [-Wpedantic]
[Note] previous declaration of 't' was here

1 个答案:

答案 0 :(得分:8)

这显然在C11中有所改变。 C99§6.7/ 3:

  

如果标识符没有链接,则除了6.7.2.3中指定的标记之外,标识符(在声明符或类型说明符中)的声明不得超过一个具有相同作用域和相同名称空间的声明。

C11§6.7/ 3:

  

如果标识符没有链接,则标识符的声明(在声明符或类型说明符中)不得超过一个具有相同作用域和相同名称空间的声明,除了:

     

- 可以重新定义typedef名称以表示与当前相同的类型,前提是该类型不是可变修改类型;

     

- 可以按照6.7.2.3中的规定重新声明标签。

虽然我找不到C11的基本原理文档,但我猜这个更改的原因是允许多个Connection:Keep-Alive Content-Disposition:attachment; filename=examplefilename.pdf Content-Type:application/pdf Date:Wed, 21 Oct 2015 13:59:45 GMT Keep-Alive:timeout=5, max=100 Server:Apache/2.2.22 Transfer-Encoding:chunked Vary:User-Agent X-Powered-By:PHP/5.3.29 struct,可能是多个标题。由于已经允许重新声明typedef / struct / union标记,enum typedef s是一个相当常见的习惯用法。

修改

@Lundin为此找到了rationale:它是为了增强与C ++的兼容性:

  

C ++允许使用与先前typedef同名的typedef重定义出现在同一作用域中,只要它命名相同的类型即可。一些C编译器允许类似的typedef重新定义作为扩展,但C99不允许它。将良性typedef重定义添加到C1x将增强与C ++的一致性,标准化一些现有实践,并安全地消除无用的约束,偶尔会对用户造成麻烦。