Can argc be zero on a POSIX system?

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.

int main(int argc, int argv[]) {
    if (argc == 0) printf("Hey!\n");
    else main(0,NULL);

    return 0;
}

Yes, it is possible. If you call your program as follows:

execl("./myprog", NULL, (char *)NULL);

Or alternately:

char *args[] = { NULL };
execv("./myprog", args);

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:

1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

int main(void) { /* ... */ } 

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent; or in some other implementation-defined manner.

2 If they are declared, the parameters to the main function shall obey the following constraints:

  • The value of argc shall be nonnegative.
  • argv[argc] shall be a null pointer.

...

Note also that this means that if argc is 0 then argv[0] is guaranteed to be NULL. How printf 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 it's not guaranteed.