为什么这个程序在 C11 中可以正常编译,但在 C99 中却不能?
why this program compiles fine in C11 but not in C99?
考虑以下程序:(查看现场演示 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
这在 C11 中(显然)已更改。 C99§6.7/3:
If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except for tags as specified in 6.7.2.3.
C11§6.7/3:
If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except that:
— a typedef name may be redefined to denote the same type as it currently does, provided that type is not a variably modified type;
— tags may be redeclared as specified in 6.7.2.3.
虽然我找不到 C11 的基本原理文档,但我猜测此更改的原因是允许多个 struct
typedef
,可能超过多个headers。因为 re-declaring struct
/union
/enum
标签已经被允许并且 typedef
ing struct
s 是一个相当常见的习语。
编辑
@Lundin 已经找到了 rationale 这个:它是为了增强与 C++ 的兼容性:
C++ allows a typedef redefinition with the same name as a previous typedef to appear in the same scope, as long as it names the same type. Some C compilers allow similar typedef redefinition as an extension, though C99 does not allow it. Adding benign typedef redefinition to C1x would enhance consistency with C++, standardize some existing practice, and safely eliminate a constraint that is unhelpful and an occasional nuisance to users.
考虑以下程序:(查看现场演示 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
这在 C11 中(显然)已更改。 C99§6.7/3:
If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except for tags as specified in 6.7.2.3.
C11§6.7/3:
If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except that:
— a typedef name may be redefined to denote the same type as it currently does, provided that type is not a variably modified type;
— tags may be redeclared as specified in 6.7.2.3.
虽然我找不到 C11 的基本原理文档,但我猜测此更改的原因是允许多个 struct
typedef
,可能超过多个headers。因为 re-declaring struct
/union
/enum
标签已经被允许并且 typedef
ing struct
s 是一个相当常见的习语。
编辑
@Lundin 已经找到了 rationale 这个:它是为了增强与 C++ 的兼容性:
C++ allows a typedef redefinition with the same name as a previous typedef to appear in the same scope, as long as it names the same type. Some C compilers allow similar typedef redefinition as an extension, though C99 does not allow it. Adding benign typedef redefinition to C1x would enhance consistency with C++, standardize some existing practice, and safely eliminate a constraint that is unhelpful and an occasional nuisance to users.