I have found the system specific definition and recommended usage practice of main()
hardly documented in context of POSIX getopt()
in OSX/Darwin, such as shown in this little test I wrote:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, const char *argv[])//this is *not* MY "prototype" of main - it is OSX!
{
int opt = 0;
int ch;
char *cvalue = NULL;
while ((ch = getopt (argc, argv, "d:")) != -1)
switch (ch){
case 'd':
cvalue = optarg;
opt = 1;
break;
case '?':
if (optopt == 'd')
printf ("Option -%c requires an argument.\n", optopt);
break;
default:
abort();
}
if(opt)printf("optarg = %s\n", optarg);
return 0;
}
The compilers issue the following, rather intimidating warnings:
gcc:
test.c: In function ‘main’:
test.c:15: warning: passing argument 2 of ‘getopt’ from incompatible pointer type
clang:
test.c:15:32: warning: passing 'const char **' to parameter of type 'char *const *'
discards qualifiers in nested pointer types [-Wincompatible-pointer-types]
while ((ch = getopt (argc, argv, "d:")) != -1)
^~~~
/usr/include/unistd.h:548:31: note: passing argument to parameter here
int getopt(int, char * const [], const char *) __DARWIN_ALIAS(getopt);
^
AFAIK, char pointers to immutable arrays are indeed incompatible with immutable pointers to
character arrays. There is not much I can do unless changing the main()
definition to
supply arguments as required by POSIX
getopt()
:
int main(int argc, char *const argv [] ){ ... }
or according to the C standard (as defined in section 5.1.2.2.1 of C11 draft standard n1570) and described in this SO post:
int main(int argc, char *argv[] ){ ... }
This silences the compiler warnings, but makes me wonder: although same manufacturer implements both C and POSIX, forking from their prototype of main()
which seemingly conflicts with their hosted environment implementation of POSIX C gives an impression of solving the problem.
As I am developing a set of UNIX command line tools in OSX, all of which must reliably redirect, pipe, stay interactive, use files
etc. in rather complex chains and critical conditions, I need a bit deeper understanding for what reason the OSX main()
should take such argument types. Has someone worked with this specific implementation of main()
, and which would the safe procedure of solving the described issue in OSX/Darwin, without inducing risks of UB or otherwise compromised functionality? This is as far as my efforts have brought me - either in conflict with the system, or with the C standard. Thanks in advance.