对于此代码:
#include<stdio.h>
void hello() { printf("hello\n"); }
void bye() { printf("bye\n"); }
int main() {
printf("%p\n", hello);
printf("%p\n", bye);
return 0;
}
在我的机器上输出:
0x80483f4
0x8048408
[第二个地址的价值更大]
on Codepad
0x8048541
0x8048511
[第二个地址值较小]
这与机器的字节序有什么关系吗?如果没有,
为什么地址排序有所不同?
另外,为什么区别差异?
0x8048541 - 0x8048511 = 0x30
0x8048408 - 0x80483f4 = 0x14
#include<stdio.h>
int main() {
int num = 1;
if(*(char *)&num == 1)
printf("Little-Endian\n");
else
printf("Big-Endian\n");
return 0;
}
答案 0 :(得分:6)
不,这与字节序无关。它与编译器和链接器有关,可以自由地在内存中按顺序排列函数定义,并且不同的编译器选择不同的内存布局策略。
答案 1 :(得分:5)
它与endinanness无关,但与C ++标准无关。 C ++不需要按照您将它们看到磁盘的顺序编写函数(并考虑跨文件链接甚至链接其他库,这是不可行的),它可以按照自己的意愿编写它们。
关于实际值之间的差异,一个编译器可能会在块周围添加防护以防止内存覆盖(或其他相关内容,通常仅在调试模式下)。并且没有什么能阻止编译器在两个函数之间编写其他函数。请记住,即使是一个简单的hello world应用程序也会附带数千个字节的可执行代码。
底线是:永远不要假设事物在内存中的位置。你的假设几乎总是错误的。为什么甚至假设?无论如何,编写正常,安全,结构化的代码都无济于事。
答案 2 :(得分:3)
函数的位置和顺序非常特定于平台,体系结构,编译器,编译器版本甚至编译器标志(尤其是那些)。
答案 3 :(得分:1)
您正在打印功能地址。这纯粹是在链接器的域中,编译器不会执行与创建程序的二进制映像有关的任何事情。除了为每个函数生成机器代码的blob之外。链接器在最终图像中排列这些blob。一些链接器具有影响订单的命令行选项,否则很少发生。
Endian-ness不能影响printf()的输出。如果指针值是在同一台机器上生成的,它知道如何正确解释字节。