为什么这个程序在 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 标签已经被允许并且 typedefing structs 是一个相当常见的习语。

编辑

@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.