1

C++ では、定数変数の初期化での数学的な宣言には余分な処理が必要ですか? または、最新のコンパイラは、.exe ファイルを作成するときに、数学計算の結果を変数内に自動的に配置しますか?

例えば:

MyClass::MyClass()
{
    const qint32 defaultX = 20;

    poButton1 = new PushButton(this);
    poButton1->move(defaultX,20);

    poButton1 = new PushButton(this);
    poButton1->move(defaultX,80);
    //...
}

メソッドの使用法 (この場合はコンストラクター) 全体で定数変数 (defaultX) を使用するコードの例です。ここで、開発者が値の由来を伝える方がよい場合があります。

MyClass::MyClass()
{
    const qint32 defaultX = 800/2 - 244 + 12 + 32 - 180; //just an example!

    poButton1 = new PushButton(this);
    poButton1->move(defaultX,20);

    poButton1 = new PushButton(this);
    poButton1->move(defaultX,80);
    //...
}

もちろん、彼はそれをコメントの中に入れることもできますが、彼がこのようにしたいと仮定しましょう (例: 彼は頭が悪い)。問題は、そのクラスのオブジェクトが初期化されているときに、数式全体が計算されるか (余分な処理が必要になるか)、または最新のコンパイラによって .exe が作成されるときに、最初の MyClass コードで見られる最適化されたコードが既に含まれているかどうかです。 ?

4

2 に答える 2

3

保証はされていませんが、最近のほとんどのコンパイラは実際に定数式を折り畳みます。ドラフト C++ 標準には、セクション5.19 定数式から、変換中に定数式を評価できるというメモがあります。

[注: 変換中に定数式を評価できます。 —注記終了]

しかし、次のコードを使用してGodboltで実験を実行できます。

#include <iostream>
int func()
{
    const  int defaultX = 800/2 - 244 + 12 + 32 - 180; //just an example!

  return defaultX ;
}

int main()
{
  std::cout << func() ;
}

実際に次のように折りたたまれていることを確認してください。

func():
  movl  $20, %eax   #,
  ret

C++11 では、常にconstexprを使用して、コンパイル時に評価されるようにすることができます。

constexpr  int defaultX = 800/2 - 244 + 12 + 32 - 180;

標準では、浮動小数点定数式に関して重要な注意事項が 1 つあります。浮動小数点演算の精度に関する仕様が不足しているため、実行時とコンパイル時の評価で異なる結果が生じる可能性があります。

[ 注: 一部のコンテキストでは、プログラムの変換中に定数式を評価する必要がありますが、プログラムの実行中に評価する場合もあります。この国際規格は浮動小数点演算の精度に制限を課していないため、変換中の浮動小数点式の評価が同じ式の評価 (または同じ値に対する同じ演算) と同じ結果をもたらすかどうかは規定されていません。 ) プログラム実行中.84 例:

 bool f() {
  char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation
  int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime
  return sizeof(array) == size;
 }

f() の値が true になるか false になるかは未定です。—例の終了] —注記の終了]

于 2014-08-07T18:02:35.980 に答える
2

単純な代入の場合に必要な単一の値に折りたたむことができる場合、コンパイラはそれを特異値に圧縮する必要がありますが、これはコンパイラの最適化フラグに依存する場合があります。確実にするために、コンパイラによって発行された命令を確認することをお勧めします。

これをより明確に表現する 1 つの方法は、クラス自体の外部で定数を宣言しますが、実装に対してローカルであり、それをクラス内で使用することです。

const qint32 myClassDefaultX = 800/2 - 244 + 12 + 32 - 180;

MyClass::MyClass() { ... }
于 2014-08-07T17:57:54.523 に答える