代码之家  ›  专栏  ›  技术社区  ›  Dana

K&R C示例中的指针类型不匹配警告[重复]

  •  7
  • Dana  · 技术社区  · 15 年前

    可能重复:
    Problem compiling K&R example

    最近我一直在通过K&R的C编程语言。

    在第5.11节中,他们介绍了指向函数的指针,在输入示例(一个快速排序实现,我们提供了指向要使用的比较函数的指针)之后,编译器发出了一个警告:条件表达式中的指针类型不匹配。(我的编译器是OSX10.5.6上的GCC4.0.1)

    示例中触发警告的行是:

     qsort((void **) lineptr, 0, nlines-1,
          (int (*)(void*, void*))(numeric ? numcmp : strcmp));
    

    这个程序没有分段错误,但是我喜欢对每一个警告都做一个或至少理解它们的原因。

    nummp的函数声明如下:

     int numcmp(char *, char *);
    

    但是根据手册,stcmp有这样的签名:

     int strcmp(const char *s1, const char *s2);
    

    由于方法签名略有不同,警告是否简单?忽视警告会有什么后果?

    3 回复  |  直到 9 年前
        1
  •  7
  •   Jared Oberhaus    15 年前

    尽管您可以隐式地将char *转换为空洞*,但是对于那些具有这些类型的函数指针(没有警告),也不能这样做。编译器对函数签名的类型匹配更为小心。

    更不用说qsort内部发生的事情是相反的:也就是说,一个void*将被转换成nummp中的char*和strcmp中的const char*。

    在这种情况下,编译器应该发出警告。如果您真的必须使用与参数不具有相同类型的函数,也许您应该使用与类型匹配的包装函数,然后在调用原始函数时执行适当的显式转换。

    例如:

    static int strcmp_wrapper(void* s1, void* s2) {
      return strcmp((char*)s1, (char*)s2);
    }
    
    static int numcmp_wrapper(void* n1, void* n2) {
      return numcmp((char*)n1, (char*)n2);
    }
    
    qsort((void **) lineptr, 0, nlines-1,
          (numeric ? numcmp_wrapper : strcmp_wrapper));
    

    qsort的现代签名是

    void
    qsort(void *base, size_t nel, size_t width,
          int (*compar)(const void *, const void *));
    

    问题 const 在你的问题上似乎没有发挥作用,但K&R没有 康斯特 .

        2
  •  3
  •   MarkusQ    15 年前

    简而言之:K&R不知道C。

    长话短说:当他们开始的时候, 没有人 他们知道C,所以他们一直在编故事。

    (稍微)长答案的轻率形式:语言已经进化(有些人会说 改变 有相当多的K和R,R是书面的,但除非你得到了动态版本变形的电子书版本,在你的副本K和R,R的例子不会跟上“新批准的”(“现在有更多的ANSI!”)语言。

        3
  •  1
  •   Uri    15 年前

    尝试诊断的一种方法是,看看如果将表达式替换为?:只有其中一个。

    如果它只发生在strcmp而不是nummp上,那么很可能是因为const char*。我认为,尽管char *总是可以转换为空隙*,但是不能将conchch* *转换为“安全”。

    如果两者都是,那么这可能是函数指针的问题,在函数指针中,将char*转换为void*是可行的,但是签名应该是相同的,并且使用void而不是char是一个问题。