目标文件如何在 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);
}