关于C/C++ 表达式求值顺序 未定义
表达式的副作用
运算符的优先级与结合性规定了表达式中相邻两个运算符的运算次序,但对于双目
运算的操作数,C++没有规定他们的计算次序。例如,对于表达式:
exp1 + exp2;
先计算 exp1 还是 exp2?不同的编译器有不同的做法。
在数学上,对于双目运算符,不论先计算哪一个操作数,要求最终计算结果一样。
在 C++中,在计算一个操作数时,该计算会改变(影响)另一个操作数,从而导致因操
作数的不同计算次序产生不同的最终计算结果。对于因操作数计算的次序不同产生不同
结果的表达式为带副作用的表达式。在计算时会影响其他操作数的值,引起副作用的运
算符为带副作用的运算符。如++、– –以及各种赋值运算符为带副作用的运算符。例如:
x=1,(x+2)*(++x)
先计算 x+2 表达式的值为 6。
若先计算++x,由于修改了 x+2 中 x 的值,计算结果为8。
在 C++中规定,先计算逻辑与(&&)和逻辑或(||)的第一个操作数,再计算第二
个操作数,以便进行短路求值。条件(?:)、逗号(,)运算符也规定了操作数的计算次序,
除此以外,其他运算符没有规定操作数的计算次序,计算次序由具体的编译器决定。因
此在含这些运算符的表达式中,避免在操作数中引入带副作用的运算符。
表达式求值顺序不同于运算结合性和优先级。下面是一个经典例子,被 ISO C99/ C++98 /03 三大标准明确提到:他的结果是不确定(unspecified) 的。
i = ++i + 1; // The behavior is unspecified
在介绍概念之前,我们先解释一下它的结果。这个表达式( expression )包含3个子表达式( subexpression ):
e1 = ++i
e2 = e1 + 1
i = e2
这三个子表达式都没有顺序点( sequence point ),而 ++ i 和 i = e3 都是有副作用( side effect )的表达式。由于没有顺序点,语言不保证这两个副作用的顺序。
更加可怕的是,如果i 是一个内建类型,并在下一个顺序点之前被改写超过一次,那么结果是未定义(undefined)的!比如本例中如果有:
int i = 0x1000fffe;
i = ++i + 1; // The result is undefined!!
你也许会认为他的结果是加1 或者加2,其实更糟糕 —— 结果可能是 0x1001ffff 。他的高字节接受了一个副作用的内容,而低字节则接受了另一个副作用的内容! 如果i 是指针,那么将很容易造
相关文档:
http://www.trendcaller.com/2009/05/hadoop-should-target-cllvm-not-java.html
Sunday, May 10, 2009
Hadoop should target C++/LLVM, not Java (because of watts)
< type="text/javascript">
digg_url="http://www.trendcaller.com/2009/05/hadoop-should-target-cllvm-not-java.html";
Over the years, ......
ADO(ActiveX Data
Object)是Microsoft数据库应用程序开发的新接口,是建立在OLE DB之上的高层数据库访问技术,即使你对OLE
DB,COM不了解也能轻松对付ADO,因为它非常简单易用,甚至比你以往所接触的ODBC API、DAO、RDO都要容易使用,并不失灵活性。
ADO(ActiveX Data Object)是Microsoft数据库应用
程序
......
#include "windows.h"
void main()
{
MessageBox(NULL, "你好啊!", "提示", MB_OK);
return 0;
}
通过windows.h文件调用windows自带的api函数MessageBox,来完成提示框,效果棒
null表示附属的窗体为空
MB_OK表示对话框的类型 ......
多继承:
C++中的类可以直接实现多继承 如:class D:public A,public B,public C{……};
Java中不能直接实现这样的多继承,但是可以用接口(interface)来间接实现 如:
public class A{ ……}
public interface C{
public void c1();
public void c2();
}
public class C exten ......