翻译单元中具有不同定义的相同结构

Dan*_*Dan 1 c

0.c

#include <stdio.h>

struct test{
 int a;
};

struct test get(int in);

int main(){
 struct test t = get(1234);
 printf("%d\n",t.a);

 return 0;
}
Run Code Online (Sandbox Code Playgroud)

1.c

struct test{
 char a;    // Note this is char instead of int.
};

struct test get(int in){
  struct test t = {in};
  return t;
}
Run Code Online (Sandbox Code Playgroud)

struct test有两种不同的定义。一个 with int,另一个 withchar作为其数据类型。

这是未定义的行为吗?C 没有one dentition rule像 C++ 那样的官方语言,这篇文章说多个定义可以吗?不同的翻译单元是否可以定义同名的结构体?

Kam*_*Cuk 5

这是未定义的行为吗?

是的。

这篇文章说多个定义可以吗?

当然可以,但当它们在两个 TU 之间使用时则不然。

问题甚至不在 处struct test t = get(1234);,而是在之前,就在函数声明处struct test get(int in);。这是规则6.2.7

2 引用同一对象或函数的所有声明应具有兼容的类型;否则,行为是未定义的。

6.7.6.3p15开始:

为了使两个函数类型兼容,两者都应指定兼容的返回类型[...]

从6.2.7p1开始:

[...] 在单独的翻译单元中声明的两个结构 [...] 是兼容的,如果它们的标签和成员满足以下要求: [...] 如果两者都在各自翻译单元内的任何位置完成,则以下附加要求apply:它们的成员之间应该是一一对应的,使得每对对应的成员都声明为兼容的类型。

文件0.c声明函数getatstruct test get(int in);和文件1.c声明函数getat struct test get(int in){...}(定义也是声明)。两者具有相同的名称,因此它们指的是相同的函数。

两者都有返回类型struct test。In0.c struct test有一个类型的成员int,并且 in1.c struct test有一个类型的成员char。两个文件中两个结构体的第一对成员的类型不兼容,因此类型struct test不兼容,因此函数声明不兼容,因此代码的行为未定义。