首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何理解排序前和重新排序?

如何理解排序前和重新排序?
EN

Stack Overflow用户
提问于 2022-01-07 15:58:30
回答 2查看 109关注 0票数 3

排序-前在C++标准中定义为

如果A是在B之前排序的,那么A的评估将在B开始评估之前完成

还有一长串关于A什么时候被排序的规则--在B之前。

但是,从这个列表中,我发现在下一个完整表达式之前对一个完整表达式进行了排序。因为一个完整的表达式语句是一个完整的表达式,所以在下面的代码中,3/4/5是完整表达式,而1/2不是(它们是声明语句)。

代码语言:javascript
复制
int main(){
    int a = 1; // 1
    int b = 2; // 2
    a = 10; // 3 
    b = 20; // 4
    printf("%d %d", a, b); // 5
}

那么,根据排序前的定义,编译器/CPU可以重新排序3/4吗?

我有两个答案:

  1. 不,他们不能 这是因为3是排序的-在4之前,所以3必须在4之前执行。
  2. 是的,罐子 根据以此类推,C++允许不改变程序可观察行为的任何和所有代码转换。由于3和4的顺序并不重要,所以编译器/CPU有充分的理由重新排序,根据似乎-if规则。

看来我在这里遇到了矛盾。

更新

怎么样

代码语言:javascript
复制
int main(){
    int a = 1; // 1
    int b = 2; // 2
    a = random_int(); // 3 
    b = random_int(); // 4
    printf("%d %d", a, b); // 5
}
EN

回答 2

Stack Overflow用户

发布于 2022-01-07 16:05:18

如果不能观察到重新排序,编译器只能重新排序3和4。

下面是 --一个(可以说)这样做的例子

生成的对象代码在10之前注册20。

代码语言:javascript
复制
.LC0:
        .string "%d %d"
main:
        sub     rsp, 8
        mov     edx, 20
        mov     esi, 10
        xor     eax, eax
        mov     edi, OFFSET FLAT:.LC0
        call    printf
        xor     eax, eax
        add     rsp, 8
        ret

另一种解释是,这不是重新排序,这些表达式已经消失了。注意,现在已经没有提到12了。

票数 1
EN

Stack Overflow用户

发布于 2022-01-07 19:23:51

您不需要担心重新排序,至少只要您的程序是单线程的。

前面的关系决定了你将要看到的行为。

然后编译器可以重新排序它想要的任何东西,只要可观察的行为符合以前的顺序。

random_int()怎么样?

不管你调用什么功能,重新排序都不会影响可观察到的行为。

因为一个完整的表达式语句是一个完整的表达式,所以在下面的代码中,3/4/5是完整表达式,而1/2不是(它们是声明语句)。

如果我们分开头发,它们中没有一个是完整的表情。:P

在……里面

代码语言:javascript
复制
int a = 1; // 1
int b = 2; // 2
a = 10; // 3 
b = 20; // 4
printf("%d %d", a, b); // 5

全表达式是:12 (初始化器),a = 10b = 20printf("%d %d", a, b).

a = 10; (带;)是表达式语句,但不是表达式.如果删除;,它将变成一个完整的表达式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70623925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档