A modern system:
% pacman -Q glibc gcc
glibc 2.16.0-4
gcc 4.7.1-6
% uname -sr
Linux 3.5.4-1-ARCH
A trivial program:
% < wtf.c
void main(){}
Let's do static and dynamic builds:
% gcc -o wtfs wtf.c -static
% gcc -o wtfd wtf.c
Everything looks fine:
% 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
Could anybody explain this to me?
% 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
Sure, one can use int main(). And -Wmain will issue a warning (return type of ‘main’ is not ‘int’).
I'd just like to understand what is going on there.
That's EXACTLY the point.
There is no "void main()". There is ALWAYS a result value, and if you don't return one and don't do anything in your program, the return value is what happens to be in the appropiate register at program start (or specifically, whatever happens to be there when main is called from the startup code). Which can certainly depend on what the program is doing before main, such as dealing with shared libs.
EDIT: to get an idea how this can happen, try this:
int foo(void)
{
return 55;
}
void main(void)
{
foo();
}
There is no guarantee, of course, but there's a good chance that this program will have an exit code of 55, simply because that's the last value returned by some function. Just imagine that call happened before main.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With