首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC语句表达式中的执行顺序

GCC语句表达式中的执行顺序
EN

Stack Overflow用户
提问于 2020-10-26 10:52:39
回答 1查看 86关注 0票数 2

我发现两个相似的语句执行顺序不同(唯一的区别是下面的语句有一个额外的;)。析构函数的顺序不同。C++对此是否有相应的规范,或者它只是一种未指定的行为?

环境: GCC10

代码语言:javascript
复制
#include <iostream>

template <int num>
struct S {
  S() {std::cout << "S(" << num << ")\n"; }
  ~S() {std::cout << "~S(" << num << ")\n"; }
};

int main() {
  ({S<1>(), S<2>();});
  std::cout << "-----------------------------------\n";
  ({S<3>(), S<4>();;});
}

输出:

代码语言:javascript
复制
S(1)
S(2)
~S(1)
~S(2)
-----------------------------------
S(3)
S(4)
~S(4)
~S(3)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-26 11:22:39

这不是标准的C++。这是一个被称为statement expression的GCC扩展。括号中的复合语句可以出现在允许使用表达式的位置。如果用大括号括起的块中的最后一条语句是表达式语句,则此表达式的值也是整个语句表达式的值;否则,语句表达式的类型为void,并且没有值。

您的第一个示例大致相当于

代码语言:javascript
复制
([](){ return S<1>(), S<2>(); })();

(这是一个创建并立即调用的lambda )。有一个逗号表达式可以创建S<1>S<2>临时文件。S<1>被销毁,从技术上讲,S<2>被复制到返回值中--但是这个副本被省略了。如果不是因为这个拷贝省略,你会看到

代码语言:javascript
复制
S<1>()
S<2>()
S<2>(S<2>&&)  // (1) move constructor
~S<2>()  // (2) the original temporary is destroyed
~S<1>()
~S<2>()  // the copy is destroyed outside of the lambda

但是省略了(1)/(2)对,留下了您在示例中观察到的序列。

在第二个例子中,大括号中的最后一条语句不是表达式,所以整个东西也没有值。它大致相当于

代码语言:javascript
复制
([](){ S<3>(), S<4>(); return; })();

这两个临时对象都是在lambda中创建和销毁的,通常的规则都适用--临时对象以相反的构造顺序销毁。

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

https://stackoverflow.com/questions/64530967

复制
相关文章

相似问题

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