考虑以下计划:(参见现场演示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
答案 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 ++的一致性,标准化一些现有实践,并安全地消除无用的约束,偶尔会对用户造成麻烦。