Pie*_*ier 3 c gcc libc dynamic-linking static-linking
现代系统:
% pacman -Q glibc gcc
glibc 2.16.0-4
gcc 4.7.1-6
% uname -sr
Linux 3.5.4-1-ARCH
Run Code Online (Sandbox Code Playgroud)
一个简单的程序:
% < wtf.c
void main(){}
Run Code Online (Sandbox Code Playgroud)
让我们做静态和动态构建:
% gcc -o wtfs wtf.c -static
% gcc -o wtfd wtf.c
Run Code Online (Sandbox Code Playgroud)
一切都很好:
% file wtf?
wtfd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x4b421af13d6b3ccb6213b8580e4a7b072b6c7c3e, not stripped
wtfs: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=0x1f2a9beebc0025026b89a06525eec5623315c267, not stripped
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释一下吗?
% for n in $(seq 1 10); do ./wtfd; echo $?; done | xargs
0 0 0 0 0 0 0 0 0 0
% for n in $(seq 1 10); do ./wtfs; echo $?; done | xargs
128 240 48 128 128 32 64 224 160 48
Run Code Online (Sandbox Code Playgroud)
当然,人们可以使用int main().并且-Wmain将发出警告(return type of ‘main’ is not ‘int’).
我只想了解那里发生了什么.
这完全是重点.
没有"void main()".总有一个结果值,如果你没有返回一个并且在你的程序中没有做任何事情,那么返回值就是在程序启动时恰好在适当的寄存器中发生的事情(或者具体地说,无论什么时候发生在那里) main从启动代码调用).这当然可以取决于程序在main之前正在做什么,例如处理共享库.
编辑:想知道如何发生这种情况,试试这个:
int foo(void)
{
return 55;
}
void main(void)
{
foo();
}
Run Code Online (Sandbox Code Playgroud)
当然不能保证,但是这个程序很可能有一个55的退出代码,因为这是某个函数返回的最后一个值.试想一下,调用发生在main之前.