4
#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 给出的错误默认编译选项要严格得多,可以通过传递一些参数来调整。

这里描述了是否允许使用多个 typedef,结果是相当复杂的。无论如何只是尽量避免重复的typedef。

4

2 回答 2

2

重复声明在 C 中是完全有效的,因此如果您在描述时取消注释这两行,您将不会看到任何错误,这与您所说的相反。

有两个不同的名称声明将是一个错误。

重复定义也是一个错误,但是 typedef 不是定义(尽管有def),它是一个声明。

于 2013-03-11T16:29:48.113 回答
1

标准库也是用户代码,通常由另一个用户编写。

取消注释上述代码的第二行仍然可以成功编译。据我了解,不允许重新定义一种类型,通过取消注释第二行和第三行来确认,这将导致一个编译错误。

在我的 gcc 上没有。(版本 4.5.3)

为什么编译器足够聪明,可以知道 uint 是在标准库或用户代码中定义的?gcc 和 clang 都给出了一致的行为。

编译器不知道用户代码和标准库中的代码之间的区别。虽然编译器可以区分标准库文件和用户代码,但我真的看不出有任何理由这样做。它所看到的只是它可以 lex/parse/codegen 的文本数据。

于 2013-03-10T21:03:01.063 回答