警告here是有道理的,但这并不能回答问题的全部。例如,下面的代码触发警告:
(int)round(M_PI);
但是从另一方面来说,下面的代码没有:
double d;
(int)(d = round(M_PI));
这也不是:
(int)M_PI;
其基本原理是,您不应该通过简单的类型转换转换为int,而应该使用round
、floor
或类似的函数。但是,使用round
仍然会触发警告,但如上所述,类型转换常量或赋值变量不会触发警告。
那么,如果从double
转换到int
有那么糟糕,那么为什么在编写(int)d
或(int)M_PI
时不触发警告呢?如果您想要转换返回值,应该以什么方式绕过警告?有没有一个警告可以更正确/合理地处理这些危险的转换?
发布于 2016-02-10 14:56:16
-Wbad-function-cast
(仅限C和Objective-C )
将函数调用强制转换为不匹配的类型时发出警告。例如,如果对返回整数类型的函数的调用强制转换为指针类型,则发出警告。
顾名思义,当您将函数调用转换为非匹配类型时,-Wbad-function-cast
才会发出警告。它不会在所有类型转换上都发出警告。这解释了为什么您的最后两个示例没有收到该警告:
(int)(d = round(M_PI));
不会触发警告,因为它会将double d
强制转换为int
after it has been assigned a value.(int)M_PI;
不会触发警告,因为它只是一个数字令牌,而不是函数调用。你是对的,从double
到int
的转换可能是不好的,因为你可能会丢失信息。您可以通过简单地将函数返回值分配给一个匹配的类型,然后在稍后进行强制转换来避免GCC警告,就像在您的两个不会触发警告的示例中一样。
当然,警告的重点并不是强迫您编写额外的代码来做同样的事情。甚至对于像round()
、the return value may be too big to fit in an int
这样“返回整数值”的函数也是如此。您应该做的是检查,以查看该值是否可以安全地强制转换为第一个。
发布于 2020-01-29 07:03:58
如果你总体上喜欢这个警告,但又对没有办法编写一个显式的强制转换来抑制它而感到恼火,那么在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()可能不会被优化掉。并且在宏中插入中间值是不卫生的。
https://stackoverflow.com/questions/35308315
复制相似问题