有没有办法预测未定义的行为或实现定义的行为?

时间:2011-10-18 18:15:08

标签: c operators

#include<stdio.h>
int main(void)
{
    int i=5;
    printf("%d", i++ + ++i);
    return 0;
}

我知道这是未定义的行为(或实现定义),不应该使用。但是编译器确实给出了输出而没有给出任何警告。那么有没有预测程序的输出?

4 个答案:

答案 0 :(得分:4)

有没有办法预测 Undefined Behavior

未定义的行为意味着编译器不需要遵循任何特定的行为,每个编译器可能会或可能不会显示相同的行为。您不能依赖于编译器对未定义行为的近似/预测输出,并在此基础上编写代码。

严格地说,避免编写任何调用未定义行为的代码。

参考:

未定义的行为(UB)由ISO / ANSI C标准定义为:

  

在使用不可移植或错误的程序构造时,对于本国际标准没有要求的错误数据或不确定值的对象的行为。
  注意:可能的未定义行为范围包括完全忽略不可预测的结果,在翻译或程序执行期间以环境特征(有或没有发出诊断消息)的文档方式执行,终止翻译或执行(发布诊断消息)

有没有办法预测实施定义的行为

是的,如果可移植性(确保您的解决方案以不同的编译器以相同的方式工作)不是您的关注点 不,如果您正在寻找便携性。

如果您正在处理特定的编译器,那么您的解决方案/项目只需要针对特定​​的编译器和环境工作,那么您可以自由使用由此显示的特定于实现的行为该环境下的编译器。


这应该是一本有趣的读物:

<强> A Guide to Undefined Behavior in C and C++.

答案 1 :(得分:2)

静态源代码分析器(例如,某些配置下的PC-Lint,Coverity Prevent,GrammaTech Code Sonar等)可以检测大多数未定义行为的情况,如图所示。

答案 2 :(得分:0)

如果您正在使用GCC,则可以使用-Wall提高警告级别(打印更多警告)。其他编译器可能有类似的设置。

答案 3 :(得分:0)

一些 编译器在发出警告方面越来越好。例如,对于gcc 4.5(但 4.3,绝对不是4.1使用的CentOS 5),代码为:

void foo(int i)
{
   int a = i   + i++;
   int b = i   + ++i;
   int c = ++i + i;
   int d = i++ + i;
   int e = ++i + i++;
   int f = i++ + ++i;
   int g = ++i + ++i;
   int h = i++ + i++;
}
对于身体的八行中的每一行,gcc将给出消息:

warning: operation on 'i' may be undefined

但Clang静态分析仪(从今年1月开始)没有。