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) は参照を最適化します。