假设我们有一个声明如下的函数:
void myFunct(unsigned char a);
在我的主程序中,我这样称呼myFunct(5000)
,我收到此警告:
“整数转换导致截断”。
编译器警告我,我传递的值大于255。
无论如何,如果声明变量const ulong test = 5000
并将其传递给myFunct myFunct(test)
,则编译器不会向我发出有关同一可能问题的警告。
有人能解释一下这种行为吗?
这个丢失的警告在我的代码中引起了一个恼人的错误,我现在担心这些问题可能出现在其他地方。
我尝试了不同的编译器,如MinGW和GHS第5版(GreenHills),两者都没有提醒我有关报告的问题。
有人能告诉我是否有办法防止此类问题?
答案 0 :(得分:4)
编译器警告不需要任何逻辑。编译器会尝试针对您可能想要了解的问题提供有用的警告,并避免因误报而浪费您的时间。任何满足这两个冲突目标的启发式都可以在编译器中实现。
这里最可能的解释是,在myFunct(5000)
中,很明显转换无法保留该值,而在myFunct(test)
中,仅仅看起来不明显在函数调用。关于后者的警告需要知道此时test
的值,并且编译器可能没有机制来确定test
的值5000
。
虽然在这个特定的例子中显然test
的值总是5000
,但预测变量值的机制在所有情况下都不能很好地运作(非const变量,其值很难预测)可能会阻止编译器编写者甚至尝试实现这样的警告。
静态分析器适应不同于编译器的目标。他们尝试至少在容易的情况下预测变量的值,其中一些可以配置为在您的示例中警告myFunct(test)
。大多数静态分析仪仍保留在不确定存在问题的情况下不发出警告的权利,并且您永远不知道他们将确定与否。但是使用静态分析器比使用编译器更容易获得警告。
请注意,myFunct
中myFunct(5000)
的参数会发生转换。 cast 是一个句法结构。没有“隐性演员”这样的东西。