目标文件如何在 C 中链接?解释这种特殊情况
How Object files get linked in C? Explain this particular situation
为什么他们打印不同的值。请详细说明。
一个文件是:
/* boo.c */
#include <stdio.h>
char main;
void p2()
{
printf("0x%X\n", main);
}
另一个文件是:
/* foo6.c */
void p2(void);
int main()
{
char ch = main;
p2();
printf("Main address is 0x%x\n",main);
printf("Char value is 0x%x\n",ch);
return 0;
}
我希望 p2 和 char ch 打印相同的值,但它们打印的值非常不同。
输出为:
0x55
Main address is 0x401110
Char value is 0x10
我无法得出这些值背后的原因(Main 和 char 值按预期工作,但不是我之前提到的 p2 输出)
char ch = main;
只是截断指向字符的指针。实现已定义,但您获得低 8 位是有意义的。
现在 char main
(未初始化)在另一个编译单元中通过直接在 char
上直接内存映射函数指针来愚弄编译器,没有任何转换:那是 未定义的行为.
(并且 printf
使用的格式与数据类型不匹配...)
试试看:char main=12;
你会得到一个多重定义的符号 main
...
它确实是未定义的行为,只是补充 - 为什么你从 p2
看到 0x55
,看看反汇编:
p2:
...
0x40052a: movzx eax,BYTE PTR [rip+0x17] # 0x400548 <main>
...
main:
0x400548: push rbp
gcc 生成的代码在函数主地址处获取第一个字节,实际上它是 push rbp
的操作码,即 0x55
您可以像这样重写 p2 代码以更好地理解它:
int main();
void p2() {
char t = ((char*)&main)[0];
printf("%x\n", t);
}
为什么他们打印不同的值。请详细说明。 一个文件是:
/* boo.c */
#include <stdio.h>
char main;
void p2()
{
printf("0x%X\n", main);
}
另一个文件是:
/* foo6.c */
void p2(void);
int main()
{
char ch = main;
p2();
printf("Main address is 0x%x\n",main);
printf("Char value is 0x%x\n",ch);
return 0;
}
我希望 p2 和 char ch 打印相同的值,但它们打印的值非常不同。 输出为:
0x55
Main address is 0x401110
Char value is 0x10
我无法得出这些值背后的原因(Main 和 char 值按预期工作,但不是我之前提到的 p2 输出)
char ch = main;
只是截断指向字符的指针。实现已定义,但您获得低 8 位是有意义的。
现在 char main
(未初始化)在另一个编译单元中通过直接在 char
上直接内存映射函数指针来愚弄编译器,没有任何转换:那是 未定义的行为.
(并且 printf
使用的格式与数据类型不匹配...)
试试看:char main=12;
你会得到一个多重定义的符号 main
...
它确实是未定义的行为,只是补充 - 为什么你从 p2
看到 0x55
,看看反汇编:
p2:
...
0x40052a: movzx eax,BYTE PTR [rip+0x17] # 0x400548 <main>
...
main:
0x400548: push rbp
gcc 生成的代码在函数主地址处获取第一个字节,实际上它是 push rbp
的操作码,即 0x55
您可以像这样重写 p2 代码以更好地理解它:
int main();
void p2() {
char t = ((char*)&main)[0];
printf("%x\n", t);
}