在我的代码中,我必须使用多个函数作为 lambdas ,例如,您应该提供给qsort
。
因此,当我传递类型int
的函数时,程序运行正常。但是当我添加另一个类型double
的函数时,出现了错误消息:
1.c:44:29:错误:无效操作数到二进制< (有'double *'和'double')
从这一行:
return (*getter)(a) < target
getter
指向的地方是:
double get_sex(struct human* a) { // it's the second function I've passed
return a->sex;
}
我通过的两个函数之间的唯一区别是第一个函数是int
,第二个函数是double
。
sometype somefunction (some parameters,
int *comparator(struct human*, double, double *(struct human*)),
double *getter(struct human*) ) {
....
}
我开始用sizeof
检查它,发现代码(*getter)(*a)
以某种方式返回4个字节而不是8个,所以它必须是指针而不是double。这就是我收到错误信息的原因
我前往Wikipedia作为示例,发现了其他()
。我添加了它们,现在它返回8个字节并且工作正常。
double (*getter)(struct human*) ) {
所以问题是:我为什么要在getter
周围添加括号,而不是comparator
周围?函数返回double
而不是int
的原因是什么?!
这是我从未听说过的语法细节。
(我使用我在Windows上安装的编译器 - 来自Perl解释器Strawberry)
答案 0 :(得分:2)
你的问题来自于:
double *getter(struct human*)
隐式转换为:
double *(*getter)(struct human*)
这就是您收到错误的原因,因为您无法比较(double *)
和double
int
您没有遇到任何问题,因为您的指针(int *)
已投放到int
并且可以进行比较。但是,您的编译器应该警告您从指针到整数的隐式转换。
这里的问题是我从未见过你可以用这种方式声明一个函数指针参数。我试着写一段代码,显然它有效。但是,这可能是GCC的一些非标准行为。定义指向函数的指针的正确方法是使用括号。即。
double (*getter)(struct human*) /* 'getter' is a pointer to function taking
struct human and returning double */
答案 1 :(得分:2)
在这个表达式中:
int myfunc( double *getter(struct human*) );
... getter
具有函数类型(函数类型返回指向double的指针)。在此:
int myfunc( double (*getter)(struct human*) );
...它有函数指针类型(指向返回double的函数类型的指针)。
函数类型和函数指针类型以相同的方式工作 ,因为在大多数情况下函数类型几乎立即衰减到函数指针类型。我相信这就是标准所说的内容:(C99,6.3.2.1/4):
函数指示符是具有函数类型的表达式。除了 当它是sizeof运算符或一元&amp;运算符的操作数时 operator,一个函数指示符,类型为''函数返回类型'' 转换为类型为''指针的表达式 函数返回类型''。
所以,你的表达:
return (*getter)(a) < target;
...根据标准将getter
从函数类型衰减到函数指针类型(类型double * (*)(struct human*)
),尽管您需要double (*)(struct human*)
。
一旦您将函数传递给somefunction
,您就会收到警告,它们是不兼容的类型,例如:
警告:从不兼容的指针类型
传递'somefunction'的参数2
答案 2 :(得分:0)
您没有提供所有代码,因此我只是猜测您正在执行以下操作:
if (comparator(h, val, getter)) { ... }
比较器包括:
return getter(h) < val;
或类似的东西。
这里的关键是运算符<
使用getter的结果。另一方面,比较器的结果是转换为布尔(好吧,不是真的:这是C.但它是同样的想法。)并且你可以隐式地将任何指针转换为布尔值(这是一个整数),没有提出任何警告。
所以会发生什么:
比较器返回int
,但
来电者期待int*
。不过那没关系;指针和整数以同样的方式返回。
调用者现在想要使用int*
,就好像它是int
一样,这也没关系。
所以没有错误。
此外,返回值的零度由意外演员和隐式转换保留,所以作为奖励,你得到正确的答案。