5 ms·
To me one curious thing about the main() function without arguments is, these arguments are still pushed onto the stack. You can find them by dereferencing a po
by doomjunky 8y ago
To me one curious thing about the main() function without arguments is, these arguments are still pushed onto the stack. You can find them by dereferencing a pointer of another stack variable and playing around with the offset.
// Just tested with mingw-gcc on Win8.1
// Maybe you need to play around with the offset, +28
int main() {
int i; // Another stack variable
printf("%d\n", (long long)&i + 28); // &argv
printf("%d\n", *((void**)((long long)&i + 28))); // argv
printf("%s\n", ((char**)*((void**)((long long)&i + 28)))[0]); // argv[0]
return 0;
}
Exclaimer: I don't know how this behaves in an embedded environment.
- ronsor 8y agototally unportable and undefined behavior
- dfox 8y agoI have strong feeling that while this obviously works on i386 linux (and probably any unix for that matter) if it works on even amd64 it's just a pure coincidence.
- colejohnson66 8y agoIt shouldn’t work on amd64 because the x64 calling convention puts the arguments in the registers first
- saagarjha 8y agoHere's what works on my Mac, compiled with clang -m32. #include <stdio.h> int main() { int i; // Another stack variable printf("%s\n", **(char ***)(&i + 8)); // argv[0] return 0; } Of course, this won't work at all on x86_64 because arguments are passed on registers instead of the stack.
- kbumsik 8y agoI don't know much about AMD64 but if the arguments are passed to registers then how it is possible to retrieve argc/argv later, as other functions likely to touch registers?
- saagarjha 8y agoThey're pushed on to the stack if another function will touch them.
- doomjunky 8y agoOn Windows this dependes on the calling convention. The calling convention determines whether function arguments are passed: In order or in reverse order. Who takes care of cleaning the stack: caller or callee? And even if the arguments are passed by stack or CPU registers. In Visual Studio you can control this behavoir with the __cdecl, __clrcall, __stdcall, __fastcall, __thiscall, __vectorcall [1] calling convention function prefixes, but this also depends on the optimization options [2] of the compiler. Passing arguments via CPU registers has a huge preformance benefit, but also some drawbacks. [1]: https://msdn.microsoft.com/en-us/library/984x0h58.aspx https://msdn.microsoft.com/en-us/library/984x0h58.aspx [2]: https://msdn.microsoft.com/en-us/library/46t77ak2.aspx https://msdn.microsoft.com/en-us/library/46t77ak2.aspx
- kbumsik 8y agoIn embedded system, many manufacturer’s default startup code does not even implement argc/argv. In that case this won’t work, or you need to implement your own startup code.
- brandmeyer 8y ago> Exclaimer: I don't know how this behaves in an embedded environment. The handful of times I've written startup code for an embedded micro, I've always passed zero arguments to the program's "command line", not even its own program name. Ie, from the perspective of _start, declare the application's entry point as int main(int argc, char argv), call it with main(0, NULL), and ignore the return value. ARM passes the first several arguments in registers anyway, so your UB trick wouldn't reveal anything interesting.
- nitrogen 8y agoSomething surprising about C is that an empty argument list doesn't mean "no arguments", it means "unspecified arguments". https://stackoverflow.com/questions/693788/is-it-better-to-use-c-void-arguments-void-foovoid-or-not-void-foo https://stackoverflow.com/questions/693788/is-it-better-to-u... Though that is unlikely to be related to the arguments passed to main.
- nineteen999 8y agoThe C standard says arguments to main() should be defined as: int main(void) or int main(int argc, char *argv[]) (or equivalent, eg. int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv). From http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf, Section 5.1.2.2.1: Program startup) EDIT: apologies for the atrocious formatting, but it wasn't clear to me how to put two asterisks in a sequence here on HN without preformatted text.
- JdeBP 8y agoIt actually has a whole other half to the sentence, following the semi-colon. * http://jdebp.eu./FGA/legality-of-void-main.html http://jdebp.eu./FGA/legality-of-void-main.html
- nineteen999 8y agoI took a detour at the footnote reference, and never came back. Interesting to note, thank you.