来自K& R C的示例中的指针类型不匹配警告

时间:2009-03-20 04:45:28

标签: c kernighan-and-ritchie

  

可能重复:
  Problem compiling K&R example

最近,我一直在研究K& R的C编程语言。

在5.11节中,它们涵盖了函数的指针,并在输入他们的示例之后 - 一个快速实现,我们提供了一个指向我们想要使用的比较函数的指针 - 我从编译器收到警告:指针类型不匹配在条件表达式中。 (我的编译器是OS X 10.5.6上的gcc 4.0.1)

触发警告的示例中的行是:

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

该程序在没有segfaulting的情况下执行,但我喜欢尽可能地发出警告,或者至少了解它们的原因。

numcmp的函数声明如下:

 int numcmp(char *, char *);

但根据联机帮助页,stcmp有这个签名:

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

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

3 个答案:

答案 0 :(得分:7)

虽然您可以隐式地将char *强制转换为void *,但对于具有这些类型的函数指针(没有警告),您不能这样做。编译器对函数签名的类型匹配更加小心。

更不用说在qsort中发生的事情恰恰相反:也就是说,void *将被转换为numcmp中的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没有const

答案 1 :(得分:3)

简短回答:K& R不知道C.

答案很长:当他们开始时,没有人知道C,所以他们有点不知所措。所以他们在进行的时候会有所补偿。

(略微)长篇答案的轻浮形式:自K& R编写以来,语言已经发展(有些人会说已经改变),但除非你有电子书版本使用动态示例变形,您的K& R副本中的示例将无法跟上“新的和已批准的”(“现在使用更多ANSI!”)语言。

答案 2 :(得分:1)

尝试和诊断它的一种方法是看看如果用?:只用两个中的一个替换表达式会发生什么。

如果它只发生在strcmp而不是numcmp,那么很可能是因为const char *。我认为虽然char *总是可以转换为void *,但你不能将const char *转换为void *为“safe”。

如果两者兼而有之,那么可能这是关于函数指针的一些问题,其中char *转换为void *有效,但签名应该相同并且有空格而不是字符是一个问题。