我们应该更喜欢临时变量,而不是C ++中的用户定义变量

问题描述 投票:0回答:5
LETS说有一个C ++函数foo()返回布尔值。

我调用此功能检查属性的状态 或获取函数调用的结果。

那么,将这种类型的功能的最佳方法是什么。

Method1:

bool flag = foo() if (flag) { // some code } else { // else some code }

Method2:

if ( foo() )
{
   // some code
}
else
{
   // some code
}
我的问题

:使用临时变量提供了编译器的机会来更好地优化。

除非我需要重复使用标志,否则我通常会选择第二个。的确,在某些情况下,它可能对调试很有用,但是我不想用编译器能够自行处理的临时变量来污染代码。

方法是将所有方法一个放在一个块中,以便在if语句之后释放标志。毫无结果的额外工作:我仍然去做方法2。

优化器将生成同样的东西。目的是可读,可理解的代码。我通常更喜欢第一个选项,因为它更容易调试(您可以在调试器中看到返回的值)。
c++ optimization
5个回答
6
投票

对于原始变量,没有很大的差异。它们都由于优化而导致生成相同的机器代码。在第一种情况下,结果也可以重复使用。

但是,如果返回的类型是带有破坏者的对象。然后,差异出现。首先,该对象将被破坏,直到退出其范围(例如,在您的情况下退出功能),第二个对象将在

if

语句中评估后立即破坏。

4
投票

我更喜欢第一种使用略有更改的方法:

2
投票
const bool flag = foo(); // const myclass &cref = foo_returning_object(); if (flag) { // some code } else { // else some code }

在这种情况下,如果需要,我可以重复使用返回的值。如果我的临时性是const引用,它将延长返回对象的寿命,并且在我的程序上没有施加开销(constructur/destructor调用)。

也是其他帖子答案,还可以更容易调试返回的值。


首先,让我们记住的比编译器对源代码的观点没有与我们相同的观点:

syntax

2
投票
视图。 furthermore,当优化器开始进行播放时,它将应用分析和转换,这些分析和转换将将

等于符号执行变成

等效
二进制。

因此,优化重要的是

Semantics

。有3种不同的句法形式可用于

if

语句:

1
投票
// with a temporary if (make()) { ... } else { ... } // with a variable already in scope auto var = make(); if (var) { ... } else { ... } // with a new variable if (auto var = make()) { ... } else { ... }

后一种语法是: { auto var = make(); if (var) { ... } else { ... } }

有语义差异:这些变量的范围不同。

在临时情况下,其寿命在执行ifelse

块之前结束

在指定的变量情况下,其寿命在其范围的末端结束,else



一般来说,寿命的差异应该可以忽略不计。尽管有些情况可能重要:如果您需要访问它,或者是否需要正确测序副作用。

可能对发射代码有一些影响:

对于内置类型:不太可能会有任何效果

对于POD类型:它可能不会明确优化
对于非POD类型:破坏者中的副作用(例如释放记忆)可能会抑制优化

    以及哪些优化?
  • well,可以在此处应用的主要优化是
    StackReuse
    ,每当对象的生命周期结束时,编译器都应自由地将其内存空间重复使用为另一个对象(请参阅
    -fstack-reuse
  • )。 如果编译器无法证明该对象不再使用,或者由于其破坏者的副作用而必须将其保持活力,那么它可能必须在此对象的堆栈上占据更多空间。如前所述,在内置类型方面,这不太可能发生(优化),但是不幸的是,我不会感到惊讶。
    它取决于情况:如果您多次使用该值(Andy只需要一次致电FOO),或者如果您可以为变量提供一个非常有意义的名称,则可能应该这样做。如果这些都不是真的,那就是风格/偏好的问题。
    
    
  • 示例(1):

std::string

示例(2):

    bool flag = foo(); if (flag) // used once { // some code } else { // else some code } bool other_flag = flag && bar(); // used twice: call bar (or not) // depending on flag
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.