对象文件如何在C中链接?解释这种特殊情况

时间:2017-03-17 21:05:22

标签: c pointers memory-address

为什么他们打印不同的值。请详细说明。 一个文件是:

    /* 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输出)

2 个答案:

答案 0 :(得分:2)

char ch = main;只是截断指向char的指针。实现定义,但你得到较低的8位是有道理的。

现在char main(未初始化)在另一个编译单元中通过内存映射char上的函数指针直接编译编译器,没有任何转换:那是未定义的行为

printf使用的格式与数据类型不匹配...)

试试:char main=12;你会得到一个多重定义的符号main ......

答案 1 :(得分:0)

它确实是未定义的行为,只是为了添加 - 为什么你会看到来自0x55的{​​{1}},看看拆解:

p2

gcc生成代码,该代码占用函数主地址的第一个字节,实际上是p2: ... 0x40052a: movzx eax,BYTE PTR [rip+0x17] # 0x400548 <main> ... main: 0x400548: push rbp 的操作码,push rbp

你可以像这样重写p2代码来更好地理解它:

0x55