Я нашел специфичное для системы определение и рекомендуемую практику использования main()
трудно задокументированных в контексте POSIX getopt()
в OSX/Darwin, например, как показано в этом небольшом тесте, который я написал:
#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;
}
Компиляторы выдают следующие, довольно пугающие предупреждения:
gcc:
test.c: In function ‘main’:
test.c:15: warning: passing argument 2 of ‘getopt’ from incompatible pointer type
лязг:
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);
^
Насколько мне известно, указатели char на неизменяемые массивы действительно несовместимы с неизменяемыми указателями на массивы символов. Я мало что могу сделать, если только не изменю определение main()
, чтобы предоставить аргументы, как того требует POSIX
getopt()
:
int main(int argc, char *const argv [] ){ ... }
или в соответствии со стандартом C (как определено в разделе 5.1.2.2.1 проекта стандарта C11 n1570) и описано в этом сообщении SO:
int main(int argc, char *argv[] ){ ... }
Это заглушает предупреждения компилятора, но заставляет задуматься: хотя один и тот же производитель реализует и C, и POSIX, разветвляется от их прототипа main()
, который, по-видимому, конфликтует с их размещенной средой реализация POSIX C создает впечатление решения проблемы.
Поскольку я разрабатываю набор инструментов командной строки для UNIX в OSX, все из которых должны надежно перенаправлять, передавать, оставаться интерактивными< /em>, использовать файлы и т. д. в довольно сложных цепочках и критических условиях, мне нужно немного глубже понять, по какой причине OSX main()
должен принимать такие типы аргументов. Кто-нибудь работал с этой конкретной реализацией main()
, и какова безопасная процедура решения описанной проблемы в OSX/Darwin, не вызывающая риска UB или иного нарушения функциональности? Это то, к чему меня привели мои усилия - либо в конфликте с системой, либо со стандартом C. Заранее спасибо.
main()
неверен. Предполагается, что этоint main (int argc, char *argv[])
или эквивалентноint main (int argc, char **argv)
. Обратите внимание на отсутствиеconst
. См. проект стандарта c11 n1570: 5.1.2.2.1 Запуск программы 2. Если они объявлены, параметры основной функции должны подчиняться следующим ограничениям: [...] — параметры argc и argv и строки, на которые указывают массивом argv должны быть изменены программой и сохранять свои последние сохраненные значения между запуском программы и завершением программы. Должны быть изменены. - person EOF   schedule 10.06.2016main()
, а использовал прототип OSXmain()
, @EOF. Я благодарен за то, что вы указали мне на тот же стандарт C, который я также цитирую в своем вопросе. Если коротко: то ли у меня конфликт с системой, то ли со стандартом - надеюсь есть решение - вот о чем мой вопрос. Тем не менее спасибо. - person user3078414   schedule 10.06.2016getopt()
принимает массив модифицируемых строк - зачем ему вообще нужно писать в них? - person Barmar   schedule 10.06.2016int main(int argc, char **argv )
в /usr/include/tidy/tidy.h. - person Chris Dodd   schedule 10.06.2016int main(int argc, const char * argv[])
— это то, как выглядит сгенерированный системой шаблон в любой версии с 10+ лет. , или в любой документации Apple, связанной сmain()
. - person user3078414   schedule 10.06.2016const char
— КАЖДЫЙ — это либоmain(int, char **)
, либоmain()
(хотя есть некоторые сломанные с типом возвратаvoid
.) - person Chris Dodd   schedule 10.06.2016