Sim*_*mca 5 c++ undefined-behavior pre-increment
我相信我想做的事情可能是有效的,因为它在两种情况下都用逗号分隔(不是典型的作业),但我不确定并且搜索不会显示有关这两个的任何内容具体情况。
在这两种情况下,我都使用变量作为两个并行数组的索引。
int a[3] = {10, 20, 30};
int b[3] = {20, 40, 60};
Run Code Online (Sandbox Code Playgroud)
情况#1:初始化数组的结构
struct testStruct {
int t1;
int t2;
};
int i = 0;
testStruct test = {a[++i], b[i]}
Run Code Online (Sandbox Code Playgroud)
最终行的预期结果:test = {20, 40}
情况#2:将数组中的特定值作为函数参数传递
void testFunc(int t1, int t2) {
// do stuff
}
int i = 0;
test(a[++i], b[i]);
Run Code Online (Sandbox Code Playgroud)
最终行的预期结果:test(20, 40)
这是有效的代码吗?如果是,它在所有编译器中都有效吗?
结果是我期望的吗?如果是这样,是因为数组还是因为逗号?
谢谢!
我建议不要在代码中使用此类“技巧”,从长远来看,这是维护噩梦,而且很难推理。几乎总是有替代方案,例如以下代码:
\n\ntestStruct test = {a[++i], b[i]}\nRun Code Online (Sandbox Code Playgroud)\n\n可以改为:
\n\n++i ;\ntestStruct test = {a[i], b[i]}\nRun Code Online (Sandbox Code Playgroud)\n\n话虽如此,这两种情况都在函数调用和初始化列表中使用逗号运算符,逗号只是语法元素,仅此而已。
\n\n您的第一种情况已明确定义,但有一些警告取决于这是 C++11 还是 C++11 之前的版本。
\n\n在这两种情况下,每个逗号后面都有一个序列点,尽管 C++11 之前的版本未指定计算顺序。因此,我们可以通过缺陷报告 430来了解 C++11 之前的情况,其中显示:
\n\n\n\n\n最近的 GCC 错误报告 (\n http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11633 ) 询问\n 有效性
\n\nRun Code Online (Sandbox Code Playgroud)\n\nint count = 23; int foo[] = { count++, count++, count++ };\n这是未定义或未指定还是其他什么?
\n
答案是(强调我的未来):
\n\n\n\n\n我相信标准很明确,上面的每个初始化表达式都是一个完整表达式(1.9 [intro.execution]/12-13;另请参阅问题 392),因此每个初始化表达式后面都有一个序列点\n表达式 (1.9 [intro.execution]/16)。我同意该标准似乎没有规定表达式求值的顺序,也许应该规定。有谁知道有一个编译器不会从左到右计算表达式?
\n
在 C++11 中,它被纳入C++11 标准草案的章节段落中8.4.5,其中写道:
\n\n\n在花括号初始化列表的初始值设定项列表中,\n 初始值设定项子句(包括任何由包扩展产生的\n (14.5.3))按照它们出现的顺序进行计算。也就是说,\n 与给定\n 初始化子句关联的每个值计算和副作用都在每个值计算和\n与其后面的任何初始化子句关联的副作用之前进行排序,\n 在以逗号分隔的列表中初始化列表。
\n
我坚持使用 C++11,因为它不会改变其余内容的答案,尽管排序的措辞确实有所不同,但结论是相同的。
\n\n第二种情况会调用未定义的行为,因为函数参数的求值顺序是未指定的,并且它们的求值相对于彼此的顺序是不确定的。1.9我们可以从第15节中看到这种未定义的行为:
\n\n\n除非另有说明,否则各个运算符的操作数和各个表达式的子表达式的求值都是无序的。[\n 注意:在程序执行期间\n 多次求值的表达式中,其子表达式的无序和不确定序\n 求值不需要在不同的求值中一致\n 执行。\xe2\x80\x94end note ] 运算符操作数的值计算在运算符结果的值计算之前进行排序。如果标量对象上的副作用相对于同一标量对象上的另一个副作用或使用同一标量对象的值的值计算来说是无序的,则行为是未定义的。
\n
并提供以下示例:
\n\nf(i = -1, i = -1); // the behavior is undefined\nRun Code Online (Sandbox Code Playgroud)\n