c++ - 使用 const 类型标记变量

标签 c++ variables reference names

我喜欢使用 const& type T = LongVariableName 在一小段代码中重新标记变量,尤其是涉及公式的代码。

例如:

const double& x = VectorNorm;
double y = a*x*x*x + b*x*x + c*x + d;

我认为编译器应该足够聪明,可以优化掉这些引用变量。这几乎总是会发生吗?什么时候不会?

最佳答案

这取决于编译器和您设置的优化选项 - 不能保证它会或不会被优化掉。启用优化的现代编译器可能会优化它,但一个更好的问题是:你应该关心吗?除非你处于每秒运行数千次的紧密循环中,否则不要担心。代码清晰度通常比削减几个时钟周期更重要。

但无论如何,让我们来看看。我通过 MinGW 使用 gcc 4.7.2。我们将使用此代码:

so.cpp:

#include <cstdio>

int main()
{
    float aReallyLongNameForAVariable = 4.2;
#ifdef SHORT_REF
    const float& x = aReallyLongNameForAVariable;
    float bar = x * x * x;
#else
    float bar = aReallyLongNameForAVariable * aReallyLongNameForAVariable * aReallyLongNameForAVariable;
#endif
    printf("bar is %f\n", bar);
    return 0;
}

没有“速记引用”,我们得到以下程序集:

g++ -S -masm=intel -o noref.S so.cpp

call    ___main
mov eax, DWORD PTR LC0
mov DWORD PTR [esp+28], eax
fld DWORD PTR [esp+28]
fmul    DWORD PTR [esp+28]
fmul    DWORD PTR [esp+28]
fstp    DWORD PTR [esp+24]
fld DWORD PTR [esp+24]
fstp    QWORD PTR [esp+4]
mov DWORD PTR [esp], OFFSET FLAT:LC1
call    _printf
mov eax, 0
leave

现在让我们使用引用:

g++ -DSHORT_REF -S -masm=intel -o ref.S so.cpp

call    ___main
mov eax, DWORD PTR LC0
mov DWORD PTR [esp+20], eax
lea eax, [esp+20]
mov DWORD PTR [esp+28], eax
mov eax, DWORD PTR [esp+28]
fld DWORD PTR [eax]
mov eax, DWORD PTR [esp+28]
fld DWORD PTR [eax]
fmulp   st(1), st
mov eax, DWORD PTR [esp+28]
fld DWORD PTR [eax]
fmulp   st(1), st
fstp    DWORD PTR [esp+24]
fld DWORD PTR [esp+24]
fstp    QWORD PTR [esp+4]
mov DWORD PTR [esp], OFFSET FLAT:LC1
call    _printf
mov eax, 0
leave

所以它有点组装。但是当我们打开优化时会发生什么?

g++ -DSHORT_REF -O2 -S -masm=intel -o ref.S so.cpp
g++ -O2 -S -masm=intel -o noref.S so.cpp

两者都生成相同的程序集:

call    ___main
fld DWORD PTR LC0
fstp    QWORD PTR [esp+4]
mov DWORD PTR [esp], OFFSET FLAT:LC1
call    _printf
xor eax, eax
leave

就是这样。现代编译器(至少是 gcc)优化了引用。

关于c++ - 使用 const 类型标记变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14407623/

相关文章:

c++ - 多线程应用程序上的 volatile C/C++

javascript - 在 json 中使用变量

java - JAXB 更新字符串列表

c++ - 如何使用 std::accumulate 和 lambda 计算平均值?

c++ - C++ 中的复合 std::istream

c++ - 如何推断模板使用的 std::bind 对象的返回类型?

javascript - 如何在 jQuery 中将 css 光标值设置为变量?

variables - 是否可以在 Jekyll _config.yml 的变量内部使用变量?

c++ - 如何创建对对象的常量引用?

c++ - 如何在不使用 variable_name.at() 的情况下引用字符串的最后一个字符?