当前位置: 首页 > 知识库问答 >
问题:

评价顺序和未定义行为

萧和同
2023-03-14
int i = 0;

i = i++;   // #0

i = ++i;   // #1

关于SO的两个主题解释了C++11上下文中的这些示例。这里说#0调用UB,#1定义良好。这里说这两个例子都没有定义。这种模棱两可让我很困惑。这篇结构良好的参考文献我已经读了三遍了,但是这个主题对我来说似乎太复杂了。

.

让我们分析示例#0:i=i++;

相应的报价有:

>

  • 内置的预增量和预减量运算符的副作用在其值计算之前被排序(由于定义为复合html" target="_blank">赋值而导致的隐式规则)

    内建赋值运算符和所有内建复合赋值运算符的副作用(左参数的修改)在左参数和右参数的值计算(但不是副作用)之后排序,并且在赋值表达式的值计算之前排序(即在返回对修改对象的引用之前)

    .

    问题:我如何应用引用的规则来确定示例的UB。如能作出尽可能简单的解释,将不胜感激。谢谢你!

  • 共有1个答案

    闻人河
    2023-03-14

    由于您的引用不是直接来自标准,我将尝试引用标准的相关部分给出一个详细的回答。“副作用”和“评价”的定义见第1.9/12段:

    访问由volatile glvalue(3.10)指定的对象,修改对象,调用库I/O函数,或者调用执行其中任何操作的函数,都是副作用,是执行环境状态的变化。表达式(或子表达式)的求值通常包括值计算(包括为glvalue求值确定对象的标识和为prvalue求值提取先前分配给对象的值)和副作用的启动。

    下一个相关部分是第1.9/15段:

    i = i++;
    

    在所有情况下,赋值都是在右操作数和左操作数的值计算之后、赋值表达式的值计算之前进行排序的。

    使用上面所有的信息,整个表达式的评估是(这个顺序不是标准保证的!):

      i++(右手边)的值计算 i(左手边)的值计算
    • i的修改(++的副作用)
    • 修改i(=)的副作用
    i = ++i;
    
    i = (i += 1)
    

    但是从上面我们已经知道,=的值计算是在操作数的值计算之后进行的,而副作用是在=的值计算之前进行的。因此我们得到了一个定义良好的评估顺序:

    1. 计算i+1值(和i-内部表达式的左手边)(#1)
    2. 启动内=的副作用,即修改“内”i
    3. 计算(i=i+1)的值,这是i
    4. 的“新”值
    5. 启动外部=副作用,即修改“外部”i
    6. 计算完整表达式值。

    (#1):在这里,i只计算一次,因为i+=1i=i+1等价,只是i只计算一次(5.17/7)。

     类似资料:
    • 问题内容: 什么是“序列点”? 未定义行为与序列点之间有什么关系? 我经常使用诸如的有趣且令人费解的表情a[++i] = i;来使自己感觉更好。为什么我应该停止使用它们? 问题答案: C 98和C 03 此答案适用于C 标准的较旧版本。该标准的C 11和C ++ 14版本没有正式包含“序列点”。操作是“先于”或“未排序”或“不确定地排序”。最终效果基本相同,但是术语不同。 免责声明:好的。这个答案

    • 问题内容: 我有一张带有类别的表: 现在,我想将select语句的结果排序为 例如。在MySQL中,您可以这样做: 但是,您将如何在SQLite中做到这一点?我没有“订购依据”字段。 问题答案:

    • 问题内容: 我正在使用ElasticSearch 2.4.2(通过Java的HibernateSearch 5.7.1.Final)。 我对字符串排序有问题。我的应用程序的语言带有变音符号,它们具有特定的字母顺序。例如,直接在after之后,在after之后,等等。因此,您应该对字符串进行如下排序: ElasticSearch首先按典型字母排序,然后将所有奇怪的字母移到最后: 我可以为Elasti

    • 在信号处理程序中使用sem_post()是否依赖于未定义的行为? 如果信号处理程序引用除errno以外的任何具有静态存储持续时间的对象,而不是通过向声明为volatile sig_atomic_t的对象赋值,或者如果信号处理程序调用本标准中定义的任何函数,而不是[显式异步信号安全函数]之一,则行为未定义。

    • 用户的评价类型可以分为显式评价和隐式评价。显式评价指的是用户明确地给出对物品的评价,最常见的例子是Pandora和YouTube上的“喜欢”和“不喜欢”按钮: 以及亚马逊的星级系统: 隐式评价 所谓隐式评价,就是我们不让用户明确给出对物品的评价,而是通过观察他们的行为来获得偏好信息。示例之一是记录用户在纽约时报网上的点击记录。 经过几周的观察之后,我们就可以为用户刻画出一个合理的模型了——她不喜欢

    • import { Rater } from 'feui'; components: { [Rater.name]: Rater } 代码演示 基础用法 <fe-cell title="设置默认" inline-desc="总共5星如果不改变的话"> <fe-rater v-model="data3" slot="value"></fe-rater> </fe-cell>