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.
#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.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.
Like what?
https://stackoverflow.com/questions/693788/is-it-better-to-u...
Though that is unlikely to be related to the arguments passed to main.
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, 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.