c程序涉及链接得到奇怪的输出

时间:2015-05-11 21:50:28

标签: c linker

s1.c

#include <stdio.h>
int foo();
struct t1 {
  int j; int k; int i;
} a; 
int main() {
  foo();
  printf("%d %d %d\n", a.i, a.j, a.k); }

s.c

struct t1 {
  int i; int j; int k;
} a;
int foo() {
  a.i = 5; a.j = 7; a.k = 9;
  return 0;
}

使用gcc s.c s1.c -o ee

进行编译

使用./ee运行,我得到以下输出: 9 5 7

我知道这与链接有关,但其中的原因是什么呢?

1 个答案:

答案 0 :(得分:4)

此程序是未定义行为的展示:当一个翻译单元中struct的声明与其他翻译单元中的定义不匹配时,程序定义不明确,并且可以执行任何操作。

在这种情况下,你很幸运,程序以相反的顺序打印数字。虽然它是在您的系统上完成的,但是您的程序不需要在另一个符合标准的系统上执行相同的操作(甚至运行!)。这是因为字段类型成对匹配(j&lt; ==&gt; ik&lt; ===&gt; ji和&lt; ===&gt; k)。如果您将ijk的类型更改为chardoubleint,您的程序可能会打印一些垃圾值或崩溃。

来自C99,6.2.7.1:

  

在单独的翻译单元中声明的两个结构,联合或枚举类型在其标记和成员满足以下要求时是兼容的:如果使用标记声明一个,则另一个应使用相同的标记声明。如果两者都是完整类型,则以下附加要求适用:其成员之间应存在一对一的对应关系,以便每对相应成员都声明为兼容类型,并且如果一个成员相应的对用名称声明,另一个成员用同名声明。对于两个结构,相应的成员应按相同的顺序声明。对于两个结构或联合,相应的位域应具有相同的宽度。对于两个枚举,相应的成员应具有相同的值。 (重点补充)