【问题标题】:sequence point and side effects序列点和副作用
【发布时间】:2015-09-15 11:09:26
【问题描述】:

根据序列点的定义,序列点是“执行序列中的指定点称为序列点,保证之前的所有副作用都是完整的

所以在下面的程序中,++ 运算符的所有副作用必须在转到 && 运算符的第二部分之前执行,即 i 应该递增到 1,因为 && 是一个序列点.

#include<stdio.h>

int main()
{
    int i=0,a;
    a=i++&&1;
    printf("%d",a);
    getchar();
    return 0;
}

预期输出:

1 (1&amp;&amp;1=1)

实际输出:

0

为什么i 在第二部分之前不增加?

使用三元运算符也可以得到相同的输出:

#include<stdio.h>

int main()
{
    int i=0,a;
    a=(i++)?1:0;

    printf("%d",a);
    getchar();
    return 0;
}

三元运算符也是一个序列点。那么这不应该给出输出 1 而不是 0 吗?

【问题讨论】:

    标签: c post-increment sequence-points


    【解决方案1】:
    i++
    

    计算为 i 的先前值。

    作为一个副作用,i 的值增加了1

    所以是的,序列点在那里,但表达式 i++ 的计算结果为 0(尽管 i 的值同时是 1

    对于预期结果use ++i instead of i++

    来自 C11 规范中的 6.5.2.4 后缀递增和递减运算符

    后缀 ++ 运算符的结果是操作数的值。作为 副作用,操作数对象的值增加(即 即,将适当类型的值 1 添加到它)。见 加法运算符和复合赋值的讨论 有关约束、类型和转换以及影响的信息 对指针的操作。结果的值计算为 在更新存储值的副作用之前排序 操作数。对于不确定顺序的函数调用, postfix ++ 的操作是单次求值。后缀++ 原子类型的对象是一个读-修改-写操作 memory_order_seq_cst 内存顺序语义。98)

    98) 可以形成指向原子对象的指针并且 E 具有 整数类型,E++等价于下面的代码序列,其中T 是E的类型:

    T *addr = &E;
    T old = *addr;
    T new;
    do {
      new = old + 1;
    } while (!atomic_compare_exchange_strong(addr, &old, new));
    

    其中 old 是操作的结果。必须特别小心 如果 E 具有浮动类型;见 6.5.16.2。)

    【讨论】:

      猜你喜欢
      • 2013-07-02
      • 2014-01-30
      • 2019-09-07
      • 2013-05-09
      • 2019-08-27
      • 2012-02-28
      • 1970-01-01
      • 2016-10-01
      • 2016-06-07
      相关资源
      最近更新 更多