C:未定义的行为事实

时间:2012-07-09 19:19:12

标签: c type-conversion

1)我已多次读过关于C中未定义行为的内容。这是关于:C在其定义中没有说明的一些行为,因此每个编译器都将实现它们但不违反C标准。例如:x= ++y*4 + ++y*3

但是,这里的任何人都可以给我两个编译器给出不同的结果吗?我觉得有兴趣用它来测试。 (在我的机器上,我只是搞砸了)

2)并且,C没有说明+ - * /操作的顺序。例如:1*2 + 3 + 4*5* /将首先计算,但我们不知道其他的。

所以根据下面的例子:如果我们有:

int a, b, c; 
// assign value for a,b,c
float result = a*b/c; // wrong
float result = (float)a*b/c; // seem true

但是,b/c仍然可以先计算,所以答案是错误的。所以,真正的类型转换应该是:

float result = a*b/(float)c

但是,几乎所有关于C的书,所有编码C的人,总是使用:(float)a*b/c。是否总是如此,或者他们相信“普通编译器”会像我们经常想的那样从左到右解决?

请告诉我这一点。

谢谢:)

2 个答案:

答案 0 :(得分:1)

对于1)你混淆了未定义的行为和未指定的行为,它们是不一样的。 你给出的这个丑陋的表达有不确定的行为;您认为未定义行为的后果只是非特定行为,即编译器选择了不同的可能性之一,这通常是您可以接受的。

未定义的行为可能会更糟糕。如果行为未定义,编译器通常可以根据自己的喜好选择任何内容,吃午餐,清空银行帐户,使计算机崩溃。不幸的是,在某些情况下编译器会做一些你在这些情况下不期望的坏事。所以,首先不要挑起UB。

答案 1 :(得分:0)

您不需要两个编译器来获取具有未定义行为的代码的不同结果。在许多(如果不是大多数)情况下,如果您更改优化设置和/或修改周围代码,单个编译器将很乐意为您生成不同的结果。