正如这里的回答所建议的那样,我打开了-Wbad-function-cast
,看看我的代码是否有任何gcc可以捕获的不良行为,并且它出现了这个例子:
unsigned long n;
// ...
int crossover = (int)pow(n, .14);
(此处crossover
是int
并不重要;它可能是unsigned long
,消息也是相同的。
这似乎是演员的一个非常普通和有用的例子。为什么这有问题?否则,是否有理由保持此警告开启?
我一般都喜欢设置很多警告,但我无法围绕这个用例。我正在处理的代码是大量的数字,并且很多时候根据需要将事物从一种类型转换为另一种类型以满足所涉及的算法的不同需求。
答案 0 :(得分:5)
你最好认真对待这个警告。
如果你想从pow的浮点结果得到整数,那就是舍入操作,必须使用round
之类的标准舍入函数来完成。使用整数转换执行此操作可能会产生意外:您通常会丢失小数部分,例如2.76
可能会以2
结束整数截断,就像2.12
最终会2
一样1}}。即使您需要此行为,也最好使用floor
函数明确指定它。这将提高代码的可读性和可支持性。
答案 1 :(得分:1)
-Wbad-function-cast
警告的效用有限。
可能,-Wall
和-Wextra
都没有启用该警告,这绝非巧合。它不适用于C ++(仅限C / Objective-C)。
您的具体示例不利用未定义的行为,也不利用实现定义的行为(参见ISO C11,第6.3.1.4节)。因此,这个警告给你零利益。
相反,如果您尝试重写代码以使-Wbad-function-cast
满意,那么您只需添加多余的函数调用,即使是最近的GCC/Clang compilers don't optimize away -O3
也是如此:
#include <math.h>
#include <fenv.h>
int f(unsigned n)
{
int crossover = lrint(floor(pow(n, .14)));
return crossover;
}
(负面示例,no warning emitted -Wbad-function-cast
但多余的函数调用)