#include <sys/types.h>
//Line 2: typedef unsigned int uint;
//Line 3: typedef unsigned int uint;
int main() {
uint a;
return 0;
}
鉴于上述C代码,它已成功编译,因为uint在<sys/types.h>
中定义。尽管它没有标准化,但它还是为Sys V兼容而添加,在代码中进行了评论。
取消注释上面代码的第二行仍然会导致成功编译。据我了解,不允许重新定义一种类型,通过取消注释第二行和第三行来确认,这将导致一个编译错误。
为什么编译器足够聪明,知道uint是在标准库或用户代码中定义的? gcc和clang都表现出一致的行为。
编辑: 在这种情况下,链接不是游戏的一部分。该错误仅在编译时重现,即(-c选项)。
添加行号以减少混淆。
编辑:
取消注释上面代码的第二行仍然会导致成功编译。据我了解,不允许重新定义一种类型,通过取消注释第二行和第三行来确认,这将导致一个编译错误。
我不知道为什么写这篇文章。显然,取消注释第2行和第3行不会导致gcc的编译错误。 Clang给出了默认编译选项的错误要严格得多,可以通过传递一些参数进行调整。
Here描述了是否允许多个typedef,结果证明它非常复杂。无论如何只是试图避免重复的typedef。
答案 0 :(得分:2)
重复声明在C中完全有效,因此如果您按照描述取消注释两行,则不会发现任何错误,与您所说的相反。
对名称进行两次不同的声明将是一个错误。
重复定义也是一个错误,但是typedef不是定义(尽管def
),它是一个声明。
答案 1 :(得分:1)
标准库也是用户代码,通常由其他用户编写。
取消注释上面代码的第二行仍然会导致成功编译。由于我&gt;理解它不允许重新定义一种类型,通过取消注释第二行和第三行来确认,这将导致一次编译错误。
在我的gcc上它没有。 (4.5.3版)
为什么编译器足够聪明,知道uint是在标准库或用户代码中定义的? gcc和clang都表现出一致的行为。
编译器不知道用户代码与标准库中的用户代码之间的区别。虽然编译器可以区分标准库文件和用户代码,但我真的没有理由这样做。它看到的只是文本数据,它可以是lex / parse / codegen。