是否允许不同的翻译单元定义具有相同名称的结构?

时间:2015-12-23 00:10:06

标签: c struct one-definition-rule

假设我有a.cb.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 ++中,我认为One Definition Rule禁止这样做。)

3 个答案:

答案 0 :(得分:8)

结构标记是无链接(C11 6.2.2 / 6)

的标识符

有关没有链接的标识符的多个定义的规则可在6.7 / 3中找到:

  

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

     
      
  • 如果类型不是可变修改类型,则可以重新定义typedef名称以表示与其当前相同的类型;
  •   
  • 标签可以按照6.7.2.3中的规定重新申报。
  •   

在你的程序中,foo的两个声明属于不同的范围,因此条件&#34;具有相同的范围&#34;不满意,因此不违反此规则。

答案 1 :(得分:1)

考虑这个问题的方法是compilation units.c文件以及包含的.h文件的嵌套层次结构包含一个compilation unit。预处理器扩展了所有.h个文件,并将整个compilation unit呈现给编译器。

compilation unit是宏,类型名称,静态标识符,枚举等的封闭命名空间。这些名称在此命名空间中不能有重复项,这些名称之外都不可见命名空间。这意味着不同的compilation unit是一个单独的,封闭的命名空间 - 而可能重用相同的标识符,只要 命名空间中没有重复项即可。

因此,您可以对某些标识符使用相同的名称,只要它们位于不同的compilation unit名称空间中。

请注意,外部可见的标识符(如非静态全局变量,函数等)在整个外部命名空间中必须是唯一的,该命名空间跨越所有compilation units链接在一起的单个可执行文件

答案 2 :(得分:0)

在C编程语言中,您所谓的类型并不重要。符号是根据类型的结构键入的,而不是根据类型名称键入的。在不同文件中对不同结构类型使用相同的结构名称是完全合法的。但是,您可以不使用不同的类型来声明相同的函数。