argv[0] always exists in normal means, it is either physical path of the executable or soft link position. Without accidents like run a program from code and forget about passing argv. That couldn't happen at all. And in fact, most cross platform program or shell even just assume argv[0] is the same as executable path (and don't give you a option to change it, because it is not possible on all platforms).
I did that once, but the target is a shell. Shells relies on argv[0] to determine what it is running as (login shell have prefix on argv[0]). So it end up blew up in a funny way.
After a bit google I realize I need to repeat the file path by myself on *nix. In windows, the spawn equivalent take a long string, anything after file path is argument. So it can't be a bug since day 1.
> In windows, the spawn equivalent take a long string, anything after file path is argument.
The tradeoff being that even reliably getting a Windows program in C to receive a given value in argv[] is awful[1], and the full rules for what happens if you’re unfortunate enough to need to pass through the shell are truly horrendous[2] (as well as, of course, nearly undocumented). Oh, and there is literally no way to pass arguments through in a batch file[3] (i.e. no reliable equivalent to "$@").
The reason is that command lines being dumb strings (as they are in DOS and consequently Windows) means that there are at least two places where command-line parsing needs to happen: in the shell, to detect shell syntax, including simply knowing where the command ends; and in the program (C runtime library startup or equivalent), to separate, unquote, and unescape the string into an arguments array. Thus there are at least two sets of escaping rules in play at the same time, which will inevitably diverge. (In Windows there are something like three and a half, given that executing from a batch file adds an additional layer of textual preprocessing and delayed expansion uses slightly different rules, but that is not inherent in the design choice, it’s just braindamage.)
I actually find this an interesting design problem (and have commented on it before[4]), because while the depths of insanity in the Unix approach (the shell tokenizes and globs) aren’t quite as unfathomable, the touch ./-rf; rm * problem that it implies still feels like something that shouldn’t happen, and I just can’t see an interesting intermediate point between those that wouldn’t substantially complicate the shell-to-entry-point interface.