6

正如此处的答案所建议的那样,我打开-Wbad-function-cast以查看我的代码是否有 gcc 可以捕获的任何不良行为,它出现了以下示例:

unsigned long n;
// ...
int crossover = (int)pow(n, .14);

(这里不是关键crossoverint它可能是unsigned long并且消息是相同的)。

这似乎是一个非常普通且有用的演员表示例。为什么这是有问题的?否则,是否有理由保持打开此警告?

我通常喜欢设置很多警告,但我无法将注意力集中在这个用例上。我正在处理的代码是大量数字化的,并且很多时候为了满足所涉及算法的不同需求,需要将事物从一种类型转换为另一种类型。

4

2 回答 2

5

你最好认真对待这个警告。

如果要从 pow 的浮点结果中获取整数,则为舍入操作,必须使用标准舍入函数之一来完成round。使用整数转换执行此操作可能会产生意外:您通常会丢失小数部分,例如2.76可能会2以整数截断2.12结束,就像以2. 即使你想要这种行为,你最好用floor函数明确地指定它。这将增加代码的可读性和可支持性。

于 2013-10-11T07:33:11.813 回答
1

警告的效用-Wbad-function-cast是有限的。

很可能,既不-Wall也不-Wextra启用该警告并非巧合。它也不适用于 C++(它仅适用于 C/Objective-C)。

您的具体示例没有利用未定义的行为或实现定义的行为(参见 ISO C11,第 6.3.1.4 节)。因此,此警告为您带来零收益。

相反,如果您尝试重写代码以使-Wbad-function-cast您满意,您只需添加多余的函数调用,即使是最近的GCC/Clang 编译器也不会优化-O3

#include <math.h>
#include <fenv.h>
int f(unsigned n)
{
  int crossover = lrint(floor(pow(n, .14)));
  return crossover;
}

(反面例子,没有警告发出-Wbad-function-cast但多余的函数调用)

于 2017-04-18T20:48:45.460 回答