在C中用POSIX getopt()实现main()和冲突数据类型的OSX实现?

时间:2016-06-10 15:18:43

标签: c macos posix darwin

我在OSX / Darwin的POSIX main()上下文中找到了getopt() 的系统特定定义和推荐用法实践,如此小测试所示我写道:

#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);
                              ^

AFAIK,指向不可变数组的char指针确实是不兼容的,带有不可变指针 字符数组。除非将main()定义更改为,否则我无能为力 根据{{​​1}} POSIX的要求提供参数:

getopt()

或根据C标准(如C11标准草案n1570第5.1.2.2.1节中所定义)和 described in this SO post

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

这使编译器警告无声,但让我想知道:虽然同一制造商同时实现C和POSIX,分叉来自int main(int argc, char *argv[] ){ ... } 的原型,看似冲突使用POSIX C的托管环境实现给人一种解决问题的印象。

当我在OSX中开发一组UNIX 命令行工具时,所有这些工具必须可靠重定向管道,保持交互式,使用文件 在相当复杂的链条和关键条件下,我需要更深入地了解OSX main()应采用这种参数类型的原因。是否有人使用main()的这个特定实现,哪个是在OSX / Darwin中解决所述问题的安全过程,而不会引起UB风险或其他功能受损?这是我的努力带给我的 - 要么与系统冲突,要么与C标准冲突。提前谢谢。

1 个答案:

答案 0 :(得分:0)

这是您的代码,因此它是您的原型。 MacOS X可能建议主要的外观,但您不受此约束。符合C标准的任何东西都可以使用。所以去添加缺少的参数。