【问题标题】:C++ "return" the result of an expressionC++“返回”表达式的结果
【发布时间】:2019-01-18 14:38:12
【问题描述】:

根据额外的括号,下面两个 return 语句之间的表达式计算有什么区别吗?

    return a++ *(-b+123.456)/999.12344;

对比

    return (a++ *(-b+123.456)/999.12344);

编程语言 C++ 标准 CPP 98'ish(C++11 之前)

希望问题很清楚。期望是完整地评估表达式。

【问题讨论】:

  • 你想用 ++a 代替吗?
  • @drescherjm • 上下文不足。 a 可以是引用参数,也可以是全局变量或成员变量。
  • 缺少的上下文是你想要的值。没有理由在这里推荐++a
  • 我试图回答 2 个问题。 1)a ++的原因是什么(鉴于缺少的上下文)2)OP为什么要添加()。虽然我很容易走错路。
  • 我认为算术表达式的具体逻辑只是分散注意力。

标签: c++ c++98


【解决方案1】:

口齿不清x(x) 相同(请参阅this answer 以获取“严格的口语”答案;)。在完整表达式周围添加括号不会改变 operator precedence 的任何内容。

PS:它对返回值优化的影响不大(详见this answer)。不过,它肯定对返回的值没有影响。

【讨论】:

  • 关于你的“PS”,确实如此;请参阅我的答案以进行演示。
  • “对返回值优化的模糊影响” - 我不确定它是否那么模糊!
  • @LightnessRacesinOrbit meh 现在我的答案只不过是指向您答案的链接集合
  • @user463035818:这是一个多么棒的索引。投赞成票!
  • @user463035818 我不想说:P
【解决方案2】:

存在差异。使用括号避免返回值优化

例如,如果a 和/或b 是所有合适的运算符都重载的对象,那么使用括号可能会给您带来对象值副本的开销。

对于普通的旧数据没有区别,受 C++11 的厌恶

decltype(auto) ub_server() { int a; return (a);}

这实际上给了你一个悬空参考

总结:除非您想要上述某些行为,否则不要使用括号,并且可能只有在使用支持评论时。

【讨论】:

  • 这种可憎的行为是否仍然存在于 C++14 和/或 C++17 中? (足够的绳子射中自己的脚。)
  • @Eljay:是的。如果不是这样,那将是一个突破性的变化。足够的绳子吹断你的整条腿。
【解决方案3】:

根据额外的括号,下面两个 return 语句之间的表达式计算有什么区别吗?

没有;括号是完全多余的在这种情况下


表达式expr 实际上与表达式(expr) 不同,您可以使用return 观察这一点,因为在后一种情况下禁止复制/移动省略:

#include <iostream>

struct T
{
    T() { std::cout << "T()\n"; }
    T(const T&) { std::cout << "T(const T&)\n"; }
    T(T&&) { std::cout << "T(T&&)\n"; }
    ~T() { std::cout << "~T()\n"; }
};

T foo()
{
    T t;
    return t;
}

T bar()
{
    T t;
    return (t);
}

int main()
{
    std::cout << "Test 1\n------\n";
    foo();
    std::cout << '\n';
    std::cout << "Test 2\n------\n";
    bar();
}

输出:

Test 1
------
T()
~T()

Test 2
------
T()
T(T&&)
~T()
~T()

(live demo)

在 C++17 之前,您可能会观察到相同的结果,因为编译器一直在尝试优化返回值。即使在您的标准 C++98 中,您也可能观察到在第一种情况下没有调用复制构造函数。

但是,嘿,这些都与简单的算术表达式无关。

【讨论】:

  • 更糟糕的是:auto baz() { T t; return (t); } 将返回一个悬空引用...
  • @Aconcagua 好像不是真的:godbolt.org/z/6thI89,你需要decltype(auto)
  • 好的,谢谢,霍尔特。仍然存在这样的情况,您可以通过添加括号来获得悬空引用...您是否碰巧知道标准在哪里定义了这个?
  • @Aconcagua 我认为这是一个好的开始:eel.is/c++draft/dcl.dcl#dcl.type.auto.deduct-5
猜你喜欢
  • 1970-01-01
  • 2017-11-22
  • 1970-01-01
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
相关资源
最近更新 更多