gpt4 book ai didi

c - block 范围内的 extern 与文件范围内的 typedef 不冲突?

转载 作者:太空宇宙 更新时间:2023-11-04 03:15:58 25 4
gpt4 key购买 nike

代码:

typedef int a;  // #1
extern int a; // #2, error

gcc 会产生错误“'a' redeclared as a different kind of symbol”,但是当我们将 extern 声明移动到 block 范围时,不会有警告,为什么?

typedef int a;  // #3
void foo() {
extern int a; // #4, ok
}

和:

char a;  // #5
void foo() {
extern int a; // #6, error
}

更新:

感谢@Yunnosch 的回复,但是还是不能回答我的问题。让我们看看#6,#5,当编译器看到#6 时,它会尝试在文件范围标识符中查找以查找是否存在相同的 'a',尽管它们在不同的范围内,但编译器会产生错误。

然后看#4,#3,当编译器看到#4时,它会发现相同的'a'以同样的方式存在,为什么它不产生错误?

@Yunnosch 和@Stargateur 都解释了一些关于不同范围的东西,这显然不是真的。我的观点是它与链接有关,但 #2 无法隐藏 #1 告诉我这也不是真的。

更新 2:

感谢@AnT,他给出了非常详细的解释。

最佳答案

typedef 名称和变量名称都是 C 中的普通标识符。它们共享相同的 namespace 。不能有两个同名声明,它们在同一作用域和同一 namespace 中声明不同的实体

6.2.1 Scopes of identifiers
2 [...] Different entities designated by the same identifier either have different scopes, or are in different name spaces.[...]

此外,正如 Stefan Ram 在 comp.lang.c 6.7/3 中所建议的那样,这里可能更加相关

6.7 Declarations
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.

无论哪种情况,关键点是您的两个声明都在相同的范围和相同的 namespace 中进行。这是您的第一个代码示例违反的要求。这就是编译器所提示的。

您的第二个和第三个代码示例在不同的范围 中声明了两个标识符a。那里没有违反 6.2.1/2。这些示例可能会遇到其他问题,但这是完全不同的情况。

你的第二个例子可能是完全有效的,前提是你在不同的翻译单元(在不同的文件范围)中定义全局 a,它的定义不会与 typedef 声明冲突。

您的第三个示例导致未定义的行为,因为 a 的外部定义指定了一个与本地 extern 声明不兼容的类型。

6.2.7 Compatible type and composite type
2 All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.

关于c - block 范围内的 extern 与文件范围内的 typedef 不冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51805323/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com