C+程序员应该知道哪些常见的未定义行为?

C+程序员应该知道哪些常见的未定义行为?

C+程序员应该知道哪些常见的未定义行为?

比如说:

a[i] = i++;


holdtom
浏览 649回答 3
3回答

不负相思意

计算函数参数的顺序是未指定行为。(这不会使你的节目崩溃,爆炸,或订购比萨饼.不像未定行为.)唯一的要求是在调用函数之前必须对所有参数进行完全评估。这是:// The simple obvious one.callFunc(getA(),getB());可以等效于以下内容:int a = getA();int b = getB();callFunc(a,b);或者这个:int b = getB();int a = getA();callFunc(a,b);这两者都可以;这取决于编译器。结果可能很重要,取决于副作用。

繁星点点滴滴

编译器可以自由地重新排序表达式的计算部分(假设含义不变)。根据原来的问题:a[i] = i++;// This expression has three parts:(a) a[i](b) i++(c) Assign (b) to (a)// (c) is guaranteed to happen after (a) and (b)// But (a) and (b) can be done in either order.// See n2521 Section 5.17// (b) increments i but returns the original value.// See n2521 Section 5.2.6// Thus this expression can be written as:int rhs  = i++;int lhs& = a[i];lhs = rhs;// orint lhs& = a[i];int rhs  = i++;lhs = rhs;双重检查锁定。一个容易犯的错误。A* a = new A("plop");// Looks simple enough.// But this can be split into three parts.(a) allocate Memory(b) Call constructor(c) Assign value to 'a'// No problem here:// The compiler is allowed to do this:(a) allocate Memory(c) Assign value to 'a'(b) Call constructor.// This is because the whole thing is between two sequence points.// So what is the big deal.// Simple Double checked lock. (I know there are many other problems with this).if (a == null) // (Point B){    Lock   lock(mutex);    if (a == null)    {        a = new A("Plop");  // (Point A).    }}a->doStuff();// Think of this situation.// Thread 1: Reaches point A. Executes (a)(c)// Thread 1: Is about to do (b) and gets unscheduled.// Thread 2: Reaches point B. It can now skip the if block//           Remember (c) has been done thus 'a' is not NULL.//           But the memory has not been initialized.//           Thread 2 now executes doStuff() on an uninitialized variable.// The solution to this problem is to move the assignment of 'a'// To the other side of the sequence point.if (a == null) // (Point B){    Lock   lock(mutex);    if (a == null)    {        A* tmp = new A("Plop");  // (Point A).        a = tmp;    }}a->doStuff();// Of course there are still other problems because of C++ support for// threads. But hopefully these are addresses in the next standard.
打开App,查看更多内容
随时随地看视频慕课网APP