具有全局变量的CLD链路时间错误
我正在阅读《计算机系统:程序员的视角》,我遇到了以下C文件: Foo.c:具有全局变量的CLD链路时间错误,c,linker,ld,C,Linker,Ld,我正在阅读《计算机系统:程序员的视角》,我遇到了以下C文件: Foo.c: void f(void); int x = 15213; int y = 15212; int main() { f(); printf("x = 0x%x y = 0x%x \n", x, y); return 0; } B.c: double x; void f() { x = -0.0; } 使用gcc-o foobar foo.c bar.c编译,并提供以下输出: x =
void f(void);
int x = 15213;
int y = 15212;
int main()
{
f();
printf("x = 0x%x y = 0x%x \n", x, y);
return 0;
}
B.c:
double x;
void f()
{
x = -0.0;
}
使用gcc-o foobar foo.c bar.c编译,并提供以下输出:
x = 0x0 y = 0x80000000
哇。因此,由于int是4字节,double是8字节(在我的系统上是这样),x的强符号在Foo.c中,x被指定为-0.0的十六进制表示,这反过来也会覆盖y
所以我想知道更多关于这方面的情况。为什么标准的C型防护装置在这里不起作用?0x0000000080000000是否被盲目写入ELF中存储x的位置,而y恰好在其旁边并被覆盖?请尽量详细说明。您违反了“一个定义规则”
外部定义是一个外部声明,也是一个
函数的定义(内联定义除外)或
对象如果在
表达式(作为sizeof或_Alignof的操作数的一部分除外
运算符,其结果是整数常量),在整个
程序中,该程序应有一个外部定义
标识符;否则,不得超过一个
这导致了未定义的行为。基本上,对于对象x
有两种定义,并且声明也有所不同。标准说
引用同一对象或函数的所有声明应具有
兼容型;否则,行为是未定义的
注:
%x
用于以无符号十六进制格式打印无符号整数,尝试使用%x
打印负数会导致未定义的行为
使用错误的格式说明符会导致未定义的行为。您是否注意到编译时会出现此警告 /usr/bin/ld:警告:符号“x”在/tmp/cciNZgVG.o中的对齐4小于8英寸/tmp/cc8pYw6O.o
这是未定义的行为。不要忽视这些警告。它会根据您分配的值生成答案 %x用于显示组成x和y的字节。关键是y被覆盖了。尝试使用%d或其他任何东西。