警告的基本原理here,但未能回答整个情况。例如,以下代码触发警告:
(int)round(M_PI);
但另一方面,以下代码并不是:
double d;
(int)(d = round(M_PI));
这不是:
(int)M_PI;
理由是你不应该通过简单的转换来转换为int,但是你应该使用round
,floor
或类似的函数。但是,使用round
仍然会触发警告,但如上所示,使用常量或指定的变量进行类型转换不会发生。
因此,如果从double
投放到int
那么不好,那么当你写(int)d
或{{1}时,为什么不会出现警告触发? }?如果你想转换返回值,应该以什么方式规避警告呢?是否有警告可以更正确/合理的方式处理这些危险的转换?
答案 0 :(得分:5)
-Wbad-function-cast
(仅限C和Objective-C)将函数调用强制转换为非匹配类型时发出警告。例如,如果对返回整数类型的函数的调用强制转换为指针类型,则发出警告。
顾名思义,-Wbad-function-cast
仅在您将函数调用投射到不匹配类型时发出警告。它并没有对所有演员发出警告。这就解释了为什么你没有收到前两个例子的警告:
(int)(d = round(M_PI));
没有触发警告,因为它正在向double d
after it has been assigned a value投射int
。(int)M_PI;
没有触发警告,因为M_PI
is usually implemented as #define M_PI 3.14159...
;它只是一个数字标记而不是函数调用。你是对的,从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()可能无法得到优化。并且在宏中插入中间值是不卫生的。