【发布时间】:2021-07-03 22:24:42
【问题描述】:
我从以下代码中得到一个错误。我用gcc6.3.0编译。
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000
char *lineptr[MAXLINES];
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void myqsort(void *lineptr[], int left, int right,
int (*comp)(void *, void *));
int numcmp(char *, char *);
int main(int argc, char *argv[])
{
int nlines;
int numeric = 0;
if (argc > 1 && strcmp(argv[1], "-n") == 0)
numeric = 1;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
myqsort((void **) lineptr, 0, nlines-1,
(int (*)(void*, void*))(numeric ? numcmp : strcmp));
writelines(lineptr, nlines);
return 0;
} else {
printf("input too big to sort\n");
return 1;
}
}
warning: pointer type mismatch in conditional expression
(int (*)(void*, void*))(numeric ? numcmp : strcmp));
^
这里是numcmp和strcmp这两个函数的原型。
int numcmp(char *, char *);
int strcmp(const char *, const char *);
在这个post 中,一位回答者说它们不兼容。但是 n1256 6.5.15 p3 这么说(用我的粗体字)
第二个和第三个操作数应满足以下条件之一:
— 两个操作数都有算术类型;
— 两个操作数具有相同的结构或联合类型;
— 两个操作数都有 void 类型;
— 两个操作数都是指向兼容类型的合格或不合格版本的指针;
— 一个操作数是指针,另一个是空指针常量;或
— 一个操作数是指向对象或不完整类型的指针,另一个是指向对象的指针 void 的合格或不合格版本。
它们不兼容,但符合标准的约束。但是为什么编译器会给出错误信息呢?我应该将int numcmp(char *, char *); 转换为int numcmp(const char *, const char *); 以使用三元运算符吗?
【问题讨论】:
-
我不知道这种特殊情况的规则,也不是一个方便的编译器,但值得让 numcmp 使用 const char 指针 无论如何 来实现 a) 更多有用并且 b) 更好地传达其不修改其参数所指向的字符串的意图。它可能很好用,你为什么不试试呢?
-
@nanofarad 我正在解决我的 C 书中的一个练习,并且该函数是以这种形式编写的。我同意你的想法,但我只是好奇为什么我的 gcc 会抱怨该消息。
-
如果两个操作数的类型为
char *和const char *,您的逻辑将适用。但它们的类型是int (*)(char *, char *)和int (*)(const char *, const char *),它们是指向两种不同类型的非限定指针。 -
您可以通读标准中的定义以说服自己“函数返回
int并采用两个char *参数”和“函数返回int并采用两个const char *参数" 是不兼容的类型。归根结底,const char和char不是兼容的类型,因为它们的条件不同:6.7.3 (9)。
标签: c language-lawyer conditional-operator