0

I have a couple of questions regarding § 5.1.2.2.2 in the standard.

  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;10) or in some other implementation-defined manner.

What does "some other implementation-defined manner" refer to? Does it refer to footnote 10, which states:

Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on.

...or the actual definition of main? If so, does this mean that given a certain implementation, the compiler can say main should be defined however it wants (this runs contrary to what I've read on the internet saying it must be int main. For example, in § 5.1.2.2.3 it states:

  1. If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;11) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

...which seems to leave a lot of leeway to the implementation.

— The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

What does "retain their last-stored values mean"? Does this mean functions like getopt violate the standard because they permute argv?

2 Answers2

2

What does "some other implementation-defined manner" refer to?

The C standard provides only two signatures for main:

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

But some implementations also allow some different signatures.

On Mac OS:

int main(int argc, char* argv[], char* envp[], char* apple[]);  

On Windows:

int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);  

POSIX supports

int main(int argc, char *argv[], char *envp[])
jacobsa
  • 5,719
  • 1
  • 28
  • 60
haccks
  • 104,019
  • 25
  • 176
  • 264
1

No; it means that Microsoft can document:

void main(int argc, char **argv, char **envp)

as a valid signature for main() on their system and it is valid as a result of the 'or in some other implementation-defined manner'.

The footnote means you can use:

typedef int num;

num main(num argc, char **argv)

and it remains valid.

See also What should main() return in C and C++.

The 'last modified values' bit means that when getopt() permutes the values in argv, the permutations it sets stay in effect until overridden by something else changing the values in argv.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278