gpt4 book ai didi

c++ - 为什么按此顺序评估 '--++a-​-++ +b--'?

转载 作者:IT老高 更新时间:2023-10-28 22:08:14 43 4
gpt4 key购买 nike

为什么下面打印的是 bD aD aB aA aC aU 而不是 aD aB aA aC bD aU?换句话说,为什么 b----++a--++ 之前被评估?

#include <iostream>
using namespace std;

class A {
char c_;
public:
A(char c) : c_(c) {}
A& operator++() {
cout << c_ << "A ";
return *this;
}
A& operator++(int) {
cout << c_ << "B ";
return *this;
}
A& operator--() {
cout << c_ << "C ";
return *this;
}
A& operator--(int) {
cout << c_ << "D ";
return *this;
}
void operator+(A& b) {
cout << c_ << "U ";
}
};

int main()
{
A a('a'), b('b');
--++a-- ++ +b--; // the culprit
}

据我所知,编译器解析表达式的方式如下:

  • 预处理器标记化:-- ++ a -- ++ + b --;
  • 运算符优先级1:(--(++((a--)++))) + (b--);
  • + 是从左到右关联的,但编译器可能会选择先计算右侧的表达式 (b--)。

我假设编译器选择这样做是因为它会导致更好的优化代码(更少的指令)。但是,值得注意的是,在使用 /Od (MSVC) 和 -O0 (GCC) 进行编译时,我得到了相同的结果。这让我想到了我的问题:

由于我在一个原则上与实现/编译器无关的测试中被问到这个问题,C++ 标准中是否有规定上述行为的内容,或者它是否真的未指定?有人可以引用标准的摘录来确认吗?在考试中提出这样的问题是错误的吗?

1 我意识到编译器并不真正了解运算符优先级或关联性,而是只关心语言语法,但这应该可以理解任何一种方式.

最佳答案

表达式语句

--++a-- ++ +b--;  // the culprit

可以用以下方式表示

一开始喜欢

( --++a-- ++ )  + ( b-- );

然后喜欢

( -- ( ++ ( ( a-- ) ++ ) ) )  + ( b-- );

终于喜欢了

a.operator --( 0 ).operator ++( 0 ).operator ++().operator --().operator  + ( b.operator --( 0 ) );

这是一个演示程序。

#include <iostream>
using namespace std;

#include <iostream>
using namespace std;

class A {
char c_;
public:
A(char c) : c_(c) {}
A& operator++() {
cout << c_ << "A ";
return *this;
}
A& operator++(int) {
cout << c_ << "B ";
return *this;
}
A& operator--() {
cout << c_ << "C ";
return *this;
}
A& operator--(int) {
cout << c_ << "D ";
return *this;
}
void operator+(A& b) {
cout << c_ << "U ";
}
};

int main()
{
A a('a'), b('b');
--++a-- ++ +b--; // the culprit

std::cout << std::endl;

a.operator --( 0 ).operator ++( 0 ).operator ++().operator --().operator + ( b.operator --( 0 ) );

return 0;
}

它的输出是

bD aD aB aA aC aU 
bD aD aB aA aC aU

你可以把函数式形式的最后一个表达式想象成形式的后缀表达式

postfix-expression ( expression-list ) 

后缀表达式在哪里

a.operator --( 0 ).operator ++( 0 ).operator ++().operator --().operator  +

表达式列表是

b.operator --( 0 )

在 C++ 标准(5.2.2 函数调用)中有这样说

8 [Note: The evaluations of the postfix expression and of the arguments are all unsequenced relative to one another. All side effects of argument evaluations are sequenced before the function is entered (see 1.9). —end note]

因此,首先评估参数还是后缀表达式是实现定义的。根据显示的输出,编译器首先评估参数,然后才是后缀表达式。

关于c++ - 为什么按此顺序评估 '--++a-​-++ +b--'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43263631/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com