我正在阅读有关评估违规的顺序,他们给出了一个令我困惑的例子.
1)如果标量对象的副作用相对于同一标量对象的另一个副作用未按顺序排列,则行为未定义.
Run Code Online (Sandbox Code Playgroud)// snip f(i = -1, i = -1); // undefined behavior
在这种情况下,i
是一个标量对象,显然意味着
算术类型(3.9.1),枚举类型,指针类型,指向成员类型的指针(3.9.2),std :: nullptr_t和这些类型的cv限定版本(3.9.3)统称为标量类型.
在这种情况下,我不明白该陈述是如何含糊不清的.在我看来,无论第一个或第二个参数是否首先被评估,i
最终都是-1
,并且两个参数也是-1
.
有人可以澄清一下吗?
我非常感谢所有的讨论.到目前为止,我非常喜欢@ harmic的答案,因为它暴露了定义这个陈述的陷阱和错综复杂,尽管它看起来有多么简单.@ acheong87指出了使用引用时出现的一些问题,但我认为这与这个问题的未测序副作用方面是正交的.
由于这个问题得到了很多关注,我将总结一下主要观点/答案.首先,请允许我进行一个小小的题外话,指出"为什么"可以具有密切相关但又略有不同的含义,即"为什么原因 ","为什么原因 "和"为了什么目的 ".我将根据他们所解决的"为什么"的含义分组答案.
这里的主要答案来自Paul Draper,Martin J提供了类似但不那么广泛的答案.Paul Draper的回答归结为
它是未定义的行为,因为它没有定义行为是什么.
答案在解释C++标准所说的内容方面总体上非常好.它还解决了UB的一些相关案例,如f(++i, ++i);
和f(i=1, i=-1);
.在第一个相关案例中,不清楚第一个论点是否应该是i+1
第二个i+2
,反之亦然; 在第二个中,不清楚i
函数调用后是否应为1或-1.这两种情况都是UB,因为它们属于以下规则:
如果相对于同一标量对象的另一个副作用,标量对象的副作用未被排序,则行为未定义.
因此,f(i=-1, i=-1)
也是UB,因为它属于同一规则,尽管程序员的意图是(恕我直言)显而易见且毫不含糊.
Paul Draper在他的结论中也明确表示
可以定义行为吗?是.它被定义了吗?没有.
这让我们想到"为什么原因/目的是 …
OpenMP标准(<= 4.0)说atomic
:
#pragma omp atomic [read | write | update | capture ] new-line
expression-stmt
where
expression-stmt
是具有以下形式之一的表达式语句:
...
If子句是更新还是不存在:
x++;
...
在前面的表达式中:
x
和v
(如果适用)都是具有标量类型的l值表达式.
...
因此,当我正确解释这一点时,以下短代码片段是非法的:
int main()
{
int myCounter = 0;
int& reference = myCounter;
#pragma omp parallel for
for (int i = 0; i < 100; ++i)
{
#pragma omp atomic
reference++; // Increment through reference.
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
原因:根据这篇文章,引用(这里int& reference
)不是标量类型.但是标准明确规定它必须是一个,才能使用atomic
.
代码用g ++编译,没有任何警告( …
class Base{};\n class Derived: public Base{};\n\n int main()\n {\n Base B;\n Derived D;\n\n Base B1 = D;//OK\n Derived D1 = B;//error: conversion from \xe2\x80\x98Base\xe2\x80\x99 to non-scalar \n //type \xe2\x80\x98Derived\xe2\x80\x99 requested\n return 1;\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n我知道派生类与基类具有 is-a 关系。
\n\n什么阻止派生 D1 具有来自 B 的值以及具有某些垃圾值的剩余成员变量(如果有)?
\n\n或者
\n\n错误信息是什么意思
\n\n\n\n\n从 \xe2\x80\x98Base\xe2\x80\x99 到非标量类型 \xe2\x80\x98Derived\xe2\x80\x99 的转换请求 Derived D1 = B;
\n
说?什么是标量类型?
\n