[...] 编译器应该足够聪明,知道 0、1、2 和 0.5 是精确的浮点值。
情况可能是这样,但是您真的希望编译器使用这些知识来抑制警告吗?考虑以下代码片段:
double fun()
{
float calculated = UNIVERSAL_BASE_VALUE;
// Do some calculations.
return calculated;
}
假设UNIVERSAL_BASE_VALUE
是在某处的头文件中定义的常量。也许它的类型是double
. 但它的值可能是 0.5,这是一个精确float
值,因此在这种情况下,编译器可以使用它的知识来抑制警告。
现在快进几年。这个好玩的功能暂时没碰过,但是生意变了,有人想试试把UNIVERSAL_BASE_VALUE
0.5的定义改成0.51。突然有一个编译器警告该函数多年来一直很稳定。为什么是这样?没有逻辑上的变化,只是一个小的数据变化。然而,该数据更改给出了UNIVERSAL_BASE_VALUE
一个无法在float
. 编译器不再对转换保持沉默。经过调查,发现calculated
这些年来的类型一直是错误的,导致fun()
返回的结果不准确。是时候责怪编译器太聪明了?:)
请注意,如果您UNIVERSAL_BASE_VALUE
用文字替换,您会遇到类似的情况0.5
。它只是让结局不那么戏剧化,而总体观点仍然成立:聪明可能会让一个错误溜走。
编译器警告旨在提醒您注意潜在的错误。这不是一门精确的科学,因为很难推断出程序员的意图,尤其是在编码风格不同的情况下。没有涵盖编译器可能选择发出的所有警告的全面标准。当出现误报时,程序员可以根据他们的具体情况做出判断。我可以想到四种基本方法可供选择。
- 关闭警告(因为它对您的代码没有真正的帮助)。
- 接受编译时会生成警告(不是一个好的选择)。
- 更改编码样式以适应警告(耗时)。
- 向编译器的开发人员抱怨(错误……很好地要求更改;不要抱怨)。
不要选择选项 2。这意味着积累人类学会忽略的警告。一旦积累了足够多的“已接受”警告,就很难发现其他弹出的警告。他们迷失在人群中,因此无法达到预期的目的。
请注意,编译器倾向于支持仅针对某些文件的某些行禁止某些警告。这在可能接受的选项 1 和 2 之间做出了折衷。
在您的情况下,您需要为您的代码库评估此警告。如果它通过发现错误来提供价值,那么您应该使用所谓的“可读性较差”。(它的可读性并没有降低,但它确实需要时间来适应它。)如果警告没有提供足够的价值来保证样式更改,请关闭警告。