-
09-12-2019 - |
質問
のコードを参照してください;
#define A 5
#define B 3
int difference = A - B;
な価値の"違い"はハードコードは"2"をコンパイル時に、取得の算出を実行?
解決
の A
や B
マクロは少しますよ!この:
#define A 5
#define B 3
int difference = A - B;
がこれと等しい:
int difference = 5 - 3;
いについて話していきましょう。
5 - 3
は 一定の表現, する表現"を評価することができ翻訳ではなくランタイム時において、その利用についてはすでに知られている一定の場合".でも*整数型定数の詳細情報がご覧いただけます例えば、ラベルがなければな整数定数式でも書けます:
switch (foo) {
case 2: /* this is a constant */
...
}
この:
switch (foo) {
case 5 - 3: /* this is a constant expression */
...
}
ただし、この定義 可 を評価した訳ないのでなければなりません。ある文脈を必要とする定数で表現し、その文脈の発現 必要 評価されるコンパイルす。
ものと仮定し difference
が宣言された内の一部の機能は、初期化はコンテキストを共有します。
他のコンパイラの分だけ支払うものでも無料)の削減 5 - 3
へ 2
コンパイル時には、コードを生成します。る店舗の価値 2
に difference
.で必ずしもそうとは限りません.Cの基準を指定します 挙動 プログラム;な方法を指定する動作が実装しなければならない.きくすることができるものとしなコンパイラを使う代わり 5 - 3
による 2
.
でも書き込んだ場合:
int difference = 2;
コンパイラが法律上のコードを生成します。る荷重の値 5
への登録を差し引 3
そこから、店舗の内容を登録へ difference
.うかいが、言語の標準的な排除します。
して最終的な結果であること difference
の値 2
, の言語の標準的なケアが出てくるんですが、それを行います。
一方、書き込んだ場合:
switch (foo) {
case 5 - 3: /* ... */
case 2: /* ... */
}
その後、コンパイラ 必要 計算の結果なので診断の誤差できない場合はラベルと同じ値とする。
最後に、設定されていない場合は difference
ファイル範囲外に機能し、その後の初期値 は する定数です。ものの区別をする場合がないかどうか 5 - 3
評価するのでコンパイル時に、そう 可 非常に発現する。
参考:最新の草案が、2011年にはC標準規格である N1570 (大PDF);一定の表現を考6.6.
他のヒント
標準はこの種のものを指定していません。それはこのような潜在的な最適化について何も言わない(そして正当な理由で。標準は、実装ではなくセマンティクスを定義します)。
あなたのコンパイラのための分解を見ないのですか?それはあなたに決定的な答えを与えるでしょう。
...
だからそれをしましょう。
VC ++ 10からの出力は:
#include <iostream>
#define A 5
#define B 3
int main() {
int x = A - B;
std::cout << x; // make sure the compiler doesn't toss it away
010A1000 mov ecx,dword ptr [__imp_std::cout (10A2048h)]
010A1006 push 2
010A1008 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (10A2044h)]
return 0;
010A100E xor eax,eax
.
わかるように、x
の発生を静的値2で置き換え、それをcout
への呼び出しのためにスタックにプッシュしました。実行時に式を評価しませんでした。