Given the standard definition for the main program:
int main(int argc, char *argv[]) {
...
}
Under which circumstances can argc
be zero on a POSIX system?
Given the standard definition for the main program:
int main(int argc, char *argv[]) {
...
}
Under which circumstances can argc
be zero on a POSIX system?
Yes, it can be zero, meaning that
argv[0] == NULL
.It's a convention that
argv[0]
is the name of the program. You can haveargc == 0
if you launch yourself the binary, like with execve family and don't give any argument. You can even give a string that is nowhere near to be the program name. That's why usingargv[0]
to get the name of the program is not entirely reliable.Usually, the shell where you type your command-line always add the program name as the first argument, but again, it's a convention. If
argv[0]
== "--help" and you use getopt to parse option, you will not detect it becauseoptind
is initialized to 1, but you can setoptind
to 0, usegetopt
and "help" long option will show up.long story short : It's perfectly possible to have
argc == 0
(argv[0]
is not really special by itself). It happen when the launcher doesn't give argument at all.whenever you want to run any executable like
./a.out
it will have one argument thats theprogram name
. But It is possible to run a program withargc
aszero
in Linux, by executing it from another program that callsexecv
with anempty argument list
.for e.g
TL;DR: Yes,
argv[0]
can be NULL, but not for any good/sane reason I know of. However, there are reasons not to care ifargv[0]
is NULL, and to specifically allow the process to crash if it is.Yes,
argv[0]
can be NULL on a POSIX system, if and only if it was executed without any arguments.The more interesting practical question is, should your program care.
The answer to that is "No, your program can assume
argv[0]
is not NULL", because some system utilities (command-line utilities) either do not work or work in a non-deterministic fashion, whenargv[0] == NULL
, but more importantly, there is no good reason (other than stupidity or nefarious purposes) why any process would do that. (I'm not sure if the standard usage ofgetopt()
also fails then — but I would not expect it to work.)A lot of code, and indeed most examples and utilities I write, begin with the equivalent of
and this is reasonable and acceptable, because there is no good reason for a process to exec another process without providing at least the command path being executed, i.e.
execlp(cmd, cmd, NULL)
rather thanexeclp(cmd, NULL)
.(However, I can think of a few nefarious reasons, like exploiting timing race windows related to pipe or socket commands: an evil process sends an evil request via an established Unix domain socket, and then immediately replaces itself with an authorized victim command (run without any arguments, to ensure minimum start-up time), so that when the service getting the request checks the peer credentials, it sees the victim command, instead of the original evil process. It is, in my opinion, best for such victim commands to crash hard and fast (
SIGSEGV
, by dereferencing a NULL pointer), rather than try and behave "nicely", giving the evil process a larger time window.)In other words, while it is possible for a process to replace itself with another but without any arguments causing
argc
to be zero, such behaviour is unreasonable, in the strict sense that there is no known non-nefarious reason to do so.Because of this, and the fact that I love making life hard for nefarious and uncaring programmers and their programs, I personally will never add the trivial check, similar to
except if requested by someone with a particular existing use case in mind. And even then I'd be a bit suspicious, wanting to verify the use case myself first.
Yes, it is possible. If you call your program as follows:
Or alternately:
Then in "myprog",
argc
will be 0.The standard also specifically allows for a 0
argc
as noted in section 5.1.2.2.1 regarding program startup in a hosted environment:Note also that this means that if
argc
is 0 thenargv[0]
is guaranteed to be NULL. Howprintf
treats a NULL pointer when used as the argument to a%s
specifier is not spelled out in the standard however. Many implementations will output "(null)" in this case but I don't believe it's guaranteed.Source
Yes but it would not be strictly conforming to POSIX.
To add to the other answers, there is nothing in C (POSIX or not) preventing main() from being called as a function within the program.