2012-11-28 28 views
2

在我的代码中,我必须使用lambda等几个函数,例如,您应该提供给qsort
所以,当我通过类型int函数,程序工作正常。但是,当我还添加double类型的另一个功能,错误消息出现了:解释这个gcc函数的类型化行为

1.c:44:29: error: invalid operands to binary < (have 'double *' and '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,所以它必须是一个指针,而不是双。这就是为什么我有这个错误信息。
我去了Wikipedia为例,发现其他()。我已经添加了它们,现在它返回8个字节并且正常工作。

 double (*getter)(struct human*)) { 

所以,问题是:我为什么要加括号周围getter但不在身边comparator?函数返回的原因是double而不是int?!
这是关于我从来没有听说过的语法细节的东西。

(我用的是我在我已经安装了Windows中发现的编译器 - 从Perl解释草莓)

+0

您应该发布一个显示问题的小型完整示例。答案很可能取决于一个小细节。 –

回答

2

你的问题来自于:

double *getter(struct human*) 

隐式转换为:

double *(*getter)(struct human*) 

这就是为什么你会得到错误,因为你不能比较(double *)double

你不必由于您的指针(int *)已投射到,因此int存在一些问题10并且可以完成比较。但是,您的编译器应警告您有关从指针到整数的隐式转换。

这里的问题是,我从来没有见过你可以用这种方式声明函数指针参数。我试图写一段代码,显然它工作。但是,这可能是GCC的一些非标准行为。定义指向函数指针的正确方法是使用圆括号。即

double (*getter)(struct human*) /* 'getter' is a pointer to function taking 
            struct human and returning double */ 
0

你没有提供所有的代码,所以我只是猜测,你正在做的事情像:

if (comparator(h, val, getter)) { ... } 

其中比较器包括:

return getter(h) < val; 

或类似的东西。

这里的关键是操作员<使用getter的结果。另一方面,比较器的结果是将转换为布尔值(当然,并非如此:这是C,但它是相同的想法。)并且可以隐式地将任何指针转换为布尔值(即整数),没有提出任何警告。

那么什么情况是:

  1. 比较返回int,但

  2. 调用者期待一个int*。没关系,不过;指针和整数以相同的方式返回。

  3. 来电者现在想要使用int*,就好像它是int一样,这也是可以的。

所以没有错误。

此外,通过意外转换和隐式转换保留了返回值的零度,所以作为奖励,您可以得到正确的答案。

2

在该表达式中:

int myfunc(double *getter(struct human*)); 

... getter具有功能类型(函数类型返回指针加倍)。虽然在此:

int myfunc(double (*getter)(struct human*)); 

...它具有函数指针类型(函数指针类型返回双)。

函数类型和函数指针类型的工作原理本质上是因为函数类型在大多数情况下几乎立即衰减为函数指针类型。我相信这是个什么标准说,在这里:(C99,6.3.2.1/4):

A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.

所以,你的表达:

return (*getter)(a) < target; 

...衰减getter从功能型到函数指针类型(类型double * (*)(struct human*)),按照标准,尽管您想要double (*)(struct human*)

你应该得到一个警告,只要你通过功能somefunction,他们是不兼容的类型的,是这样的:

warning: passing argument 2 of ‘somefunction’ from incompatible pointer type

而且,看到这个answer for detailsas well as this interesting one