什么是-Wbad-function-cast的目的,为什么它只适用于直接返回值?

时间:2016-02-10 06:29:04

标签: c gcc-warning

警告的基本原理here,但未能回答整个情况。例如,以下代码触发警告:

(int)round(M_PI);

但另一方面,以下代码并不是:

double d;
(int)(d = round(M_PI));

这不是:

(int)M_PI;

理由是你不应该通过简单的转换来转换为int,但是你应该使用roundfloor或类似的函数。但是,使用round仍然会触发警告,但如上所示,使用常量或指定的变量进行类型转换不会发生。

因此,如果从double投放到int那么不好,那么当你写(int)d或{{1}时,为什么不会出现警告触发? }?如果你想转换返回值,应该以什么方式规避警告呢?是否有警告可以更正确/合理的方式处理这些危险的转换?

2 个答案:

答案 0 :(得分:5)

  

-Wbad-function-cast(仅限C和Objective-C)

     

将函数调用强制转换为非匹配类型时发出警告。例如,如果对返回整数类型的函数的调用强制转换为指针类型,则发出警告。

顾名思义,-Wbad-function-cast仅在您将函数调用投射到不匹配类型时发出警告。它并没有对所有演员发出警告。这就解释了为什么你没有收到前两个例子的警告:

你是对的,从double投射到int可能会很糟糕,因为你可能会丢失信息。您可以通过简单地将函数返回值分配给匹配类型,然后再进行转换来避免GCC警告,就像在两个不触发警告的示例中一样。

当然,警告的重点不是强迫你编写额外的代码来做同样的事情。即使对于"返回整数值的函数"比如round()the return value may be too big to fit in an int。您应该做的是检查该值是否安全第一次

答案 1 :(得分:0)

如果您总体上喜欢警告,但又对无法编写禁止它的显式强制转换感到恼火,则可以在GCC上执行以下操作:

_Pragma ("GCC diagnostic push");                            
_Pragma ("GCC diagnostic ignored \"-Wbad-function-cast\"");
OCR1A = ((uint16_t) (function_returning_double));          
_Pragma ("GCC diagnostic pop");   

我只会在您不想引入中间值的情况下(即在宏中)使用此方法。正如其他人指出的那样(在此处:What is the purpose of gcc's -Wbad-function-cast?),免费的lrint()/ lround()可能无法得到优化。并且在宏中插入中间值是不卫生的。