看简单的例子:
int a = 0;
int b = (a ++ , a + 1); // result of b is UB or well defined ? (c++03).
Run Code Online (Sandbox Code Playgroud)
这在c ++ 11/c ++ 14中有所改变吗?
从版本1.80开始,Cppcheck告诉我
表达式'msg [ipos ++] =校验和(&msg [1],ipos-1)'取决于副作用的评估顺序
在这个代码序列中(简化,data是一个变量)
BYTE msg[MAX_MSG_SIZE]; // msg can be smaller, depending on data encoded
int ipos = 0;
msg[ipos++] = MSG_START;
ipos += encode(&msg[ipos], data);
msg[ipos++] = checksum(&msg[1], ipos-1); // <---- Undefined Behaviour?
msg[ipos++] = MSG_END; // increment ipos to the actual size of msg
Run Code Online (Sandbox Code Playgroud)
并将此视为错误,而不是可移植性问题.
它是C代码(包含在C++主导的项目中),使用C++ 98兼容编译器编译,同时按预期运行数十年.Cppcheck使用C++ 03,C89,自动检测语言运行.
我承认代码应该更好地重写.但在此之前,我试图弄清楚:它真的依赖于评估顺序吗?根据我的理解,正在首先评估正确的操作数(它需要在调用之前),然后msg[ipos]使用ipos最后完成的增量进行赋值(to ).
我错了这个假设,还是只是假阳性?
我在C++ 11中经历了关于Undefined Behavior和Sequenced [Before/After]关系的优秀答案.我理解二元关系概念,但我不知道管理测序的新规则是什么.
对于这些熟悉的示例,新的排序规则如何应用?
i = ++i;a[++i] = i;更具体地说,新的C++ 11排序规则是什么?
我正在寻找一些规则(这个是完全组成的)
在
lhs一个的'='语句总是前的测序rhs,并且首先是这样评价.
如果这些标准本身可用,有人可以在这里引用相同的内容吗?
新标准具有与旧标准不同的未定义行为.例如,新的排序规则意味着现在定义了一些过去未定义的算术运算(出于诸如序列点之间的多次写入的原因).
那么,我们需要重新学习未定义的行为?
在C++ 11标准的上下文中(不再有序列点的概念,如您所知),我想了解如何定义两个最简单的示例.
int i = 0;
i = i++; // #0
i = ++i; // #1
Run Code Online (Sandbox Code Playgroud)
SO上有两个主题可以解释C++ 11环境中的这些示例.这里据说#0调用UB并且#1定义明确.这里有人说,这两个例子是不确定的.这种模棱两可让我很困惑.我已经三次读过这个结构良好的参考文献,但这个主题似乎对我来说太复杂了.
.
让我们分析一下这个例子#0:i = i++;.
相应的报价是:
内置后增量和后减量运算符的值计算在其副作用之前进行排序.
内置赋值运算符和所有内置复合赋值运算符的副作用(左参数的修改)在左右参数的值计算(但不是副作用)之后排序,并在之前排序赋值表达式的值计算(即,在返回对修改对象的引用之前)
如果相对于同一标量对象的另一个副作用,标量对象的副作用未被排序,则行为未定义.
当我得到它时,赋值运算符的副作用没有按其左右参数的副作用排序.因此,赋值运算符的副作用没有按副作用排序i++.所以#0调用一个UB.
.
让我们分析一下这个例子#1:i = ++i;.
相应的报价是:
内置preincrement和predecrement运算符的副作用在其值计算之前被排序(由于定义为复合赋值的隐式规则)
内置赋值运算符和所有内置复合赋值运算符的副作用(左参数的修改)在左右参数的值计算(但不是副作用)之后排序,并在之前排序赋值表达式的值计算(即,在返回对修改对象的引用之前)
如果相对于同一标量对象的另一个副作用,标量对象的副作用未被排序,则行为未定义.
我看不出,这个例子是怎样的#0.对于我而言,这似乎是一个UB,原因与此相同#0.分配的副作用没有按照副作用排序++i.它似乎是一个UB.上面讨论的主题说它定义明确.为什么?
.
问题:如何应用引用规则来确定示例的UB.一个尽可能简单的解释将不胜感激.谢谢!
在C和C++语言中,该arr[i] = i++;语句调用未定义的行为.为什么语句i = i + 1;不会调用未定义的行为?
为什么以下用C++编译?
int phew = 53;
++++++++++phew ;
Run Code Online (Sandbox Code Playgroud)
相同的代码在C中失败,为什么?
有人可以向我解释为什么这个代码打印14?我刚刚被另一名学生问过,无法弄明白.
int i = 5;
i = ++i + ++i;
cout<<i;
Run Code Online (Sandbox Code Playgroud) 我已经开始研究C++ 0x了.我偶然发现了以下表达方式:
int l = 1, m=2;
++l *= m;
Run Code Online (Sandbox Code Playgroud)
我不知道第二个表达式是否有明确定义的行为.所以我在这里问.
不是UB吗?我只是渴望知道.
编辑:尚未回答 - 链接的问题是关于普通的r值,初始化列表是一个单独的,如果相关的概念.
这个语句定义得很好,或者在初始化列表中使用前缀增量运算符,对于在列表中出现两次的变量,未定义的行为?
struct T t = { i, ++i };
Run Code Online (Sandbox Code Playgroud)
我对ANSI C最感兴趣,但知道其他版本的C和/或C++是否有所不同也很有用.如果类似以下的类似结构是合法的:
struct T t = { i, i++ };
struct T t = { ++i, ++i };
struct T t = { i++, ++i };
struct T t = { i++, i++ };
Run Code Online (Sandbox Code Playgroud)