是否允许不同的翻译单元定义具有相同名称的结构?
Are different translation units allowed to define structures with the same name?
假设我有 a.c
和 b.c
,它们都定义了名为 struct foo
的类型,但定义不同:
#include <stdio.h>
struct foo {
int a;
};
int a_func(void) {
struct foo f;
f.a = 4;
printf("%d\n", f.a);
return f.a * 3;
}
#include <stdio.h>
struct foo { // same name, different members
char *p1;
char *p2;
};
void b_func(void) {
struct foo f;
f.p1 = "hello";
f.p2 = "world";
printf("%s %s\n", f.p1, f.p2);
}
在 C 中,这些文件是否可以作为符合标准的程序的一部分链接在一起?
(在 C++ 中,我相信这是被单一定义规则禁止的。)
在 C 编程语言中,您如何称呼您的类型并不重要。符号是根据类型的结构来分类的,而不是根据类型名称。不同文件中的不同结构类型使用相同的结构名称是完全合法的。但是,您不能使用不同的类型来声明相同的函数。
结构标签是 无链接 (C11 6.2.2/6)
的标识符
在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.
在你的程序中,foo
的两个声明在不同的范围内,因此不满足条件"with the same scope",因此不违反此规则。
考虑这个问题的方法是compilation units
。 .c
文件连同包含的 .h
文件的嵌套层次结构一起构成了一个 compilation unit
。预处理器展开所有 .h
文件,并将整个 compilation unit
呈现给编译器。
A compilation unit
是一个封闭的命名空间,用于宏、类型名称、静态标识符、枚举等。这些名称在此命名空间内不能重复,和 none 这些名字在这个命名空间之外是可见的。这意味着不同的 compilation unit
是一个单独的、封闭的命名空间——并且 可以 重用相同的标识符,只要 that命名空间。
因此,您可以对某些标识符使用相同的名称,只要它们位于单独的 compilation unit
命名空间中即可。
请注意,非静态全局变量、函数等外部可见标识符在整个 external 命名空间中必须是唯一的,该命名空间跨越所有 compilation units
链接合并成一个可执行文件。
假设我有 a.c
和 b.c
,它们都定义了名为 struct foo
的类型,但定义不同:
#include <stdio.h>
struct foo {
int a;
};
int a_func(void) {
struct foo f;
f.a = 4;
printf("%d\n", f.a);
return f.a * 3;
}
#include <stdio.h>
struct foo { // same name, different members
char *p1;
char *p2;
};
void b_func(void) {
struct foo f;
f.p1 = "hello";
f.p2 = "world";
printf("%s %s\n", f.p1, f.p2);
}
在 C 中,这些文件是否可以作为符合标准的程序的一部分链接在一起?
(在 C++ 中,我相信这是被单一定义规则禁止的。)
在 C 编程语言中,您如何称呼您的类型并不重要。符号是根据类型的结构来分类的,而不是根据类型名称。不同文件中的不同结构类型使用相同的结构名称是完全合法的。但是,您不能使用不同的类型来声明相同的函数。
结构标签是 无链接 (C11 6.2.2/6)
的标识符在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.
在你的程序中,foo
的两个声明在不同的范围内,因此不满足条件"with the same scope",因此不违反此规则。
考虑这个问题的方法是compilation units
。 .c
文件连同包含的 .h
文件的嵌套层次结构一起构成了一个 compilation unit
。预处理器展开所有 .h
文件,并将整个 compilation unit
呈现给编译器。
A compilation unit
是一个封闭的命名空间,用于宏、类型名称、静态标识符、枚举等。这些名称在此命名空间内不能重复,和 none 这些名字在这个命名空间之外是可见的。这意味着不同的 compilation unit
是一个单独的、封闭的命名空间——并且 可以 重用相同的标识符,只要 that命名空间。
因此,您可以对某些标识符使用相同的名称,只要它们位于单独的 compilation unit
命名空间中即可。
请注意,非静态全局变量、函数等外部可见标识符在整个 external 命名空间中必须是唯一的,该命名空间跨越所有 compilation units
链接合并成一个可执行文件。