【问题标题】:why this program compiles fine in C11 but not in C99? [duplicate]为什么这个程序在 C11 中编译得很好,但在 C99 中编译得不好? [复制]
【发布时间】:2015-10-21 14:16:44
【问题描述】:

考虑以下程序:(参见现场演示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

【问题讨论】:

  • 编译器是给你提示还是拒绝编译而不产生任何错误信息?
  • @PravasiMeet 我没有,因为我今天没有任何选票,但可能是因为您的问题不够彻底,并且您遇到的错误丢失了。
  • 有趣。你想对这些警告/错误保密吗?或者你能和我们分享一下吗?
  • 养成包含来自编译器/链接器的任何错误/警告消息的习惯。
  • @PravasiMeet 如果有的话,抱怨反对票会吸引更多人。你的问题是否表明研究和努力是由社区决定的,而不是你。

标签: c struct typedef c99 c11


【解决方案1】:

这在 C11 中(显然)已更改。 C99§6.7/3:

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

C11§6.7/3:

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

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

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

虽然我找不到 C11 的基本原理文档,但我猜测此更改的原因是允许多个 structtypedefs,可能在多个标题上。由于已经允许重新声明struct/union/enum 标签,并且typedefing structs 是一个相当常见的习语。

编辑

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

C++ 允许与前一个 typedef 同名的 typedef 重定义出现在相同的范围内,只要它命名相同的类型。一些 C 编译器允许将类似的 typedef 重新定义作为扩展,尽管 C99 不允许这样做。向 C1x 添加良性的 typedef 重新定义将增强与 C++ 的一致性,标准化一些现有的实践,并安全地消除对用户无用和偶尔滋扰的约束。

【讨论】:

  • 这有多奇怪?我相信你并投了赞成票,但我只是想知道他们为什么这样做?
  • @MartinJames 我也觉得很奇怪。我的猜测是允许多个标题上的多个typedefs 相同的东西,就像标签一样。尤其是因为typedef struct { ... } type; 组合非常受欢迎。
  • @Kninnug 我链接的副本的答案似乎表明这确实是为了 C++ 协调。这是我能找到的唯一解释。
  • 找到rationale
  • @Lundin 不错。编辑了我的答案,因为它仍然值得......
猜你喜欢
  • 2015-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
相关资源
最近更新 更多