我找到了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;
}
编译器发出以下相当吓人的警告:
海湾合作委员会:
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);
^
据我所知,指向不可变数组的字符指针确实不兼容
字符数组。除非更改 main()
,否则我无能为力。定义为
根据 POSIX
的要求提供参数getopt()
:
int main(int argc, char *const argv [] ){ ... }
或根据 C 标准(如 C11 标准草案 n1570 第 5.1.2.2.1 节中所定义)和 described in this SO post :
int main(int argc, char *argv[] ){ ... }
这消除了编译器警告,但让我想知道:尽管同一制造商同时实现了 C 和 POSIX,从他们的 main()
原型(prototype)中 fork 这似乎与他们的 POSIX C 的托管环境实现 相冲突,给人一种解决问题的印象。
当我在 OSX 中开发一套 UNIX 命令行工具时,所有这些工具都必须可靠地重定向、管道,保持交互式,使用文件
等在相当复杂的链条和关键条件下,我需要更深入地了解 OSX main()
的原因。应该采用这样的参数类型。有人使用过 main()
的这个具体实现吗? ,在 OSX/Darwin 中解决所描述问题的安全程序是什么,而不会引起 UB 风险或以其他方式损害功能?这是我的努力带给我的——要么与系统冲突,要么与 C 标准冲突。提前致谢。
最佳答案
这是您的代码,所以它是您的原型(prototype)。 MacOS X 可能会建议 main 的外观,但您不受其约束。任何符合 C 标准的东西都可以工作。所以去添加缺少的参数。
关于c - main() 的 OSX 实现以及与 C 中的 POSIX getopt() 冲突的数据类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37751785/