6

私が理解している限りでは、constexpr は、指定された式をコンパイル時に評価できるかどうかを確認し、可能であればそうするためのコンパイラへのヒントと見なすことができます。

constexpr として宣言された関数または初期化にもいくつかの制限が課されることは知っていますが、最終的な目標はコンパイル時の評価ですね。

だから私の質問は、なぜそれをコンパイラに任せることができないのですか? 前提条件をチェックできることは明らかですが、式ごとに実行し、可能な場合はコンパイル時に評価しないのはなぜですか?

なぜそうなるのかについては 2 つの考えがありますが、それが的を射ているとはまだ確信が持てません。

a) コンパイル時に時間がかかりすぎる可能性があります。

b) 私のコードでは、通常の関数が許可されない場所で constexpr 関数を使用できるため、指定子も一種の宣言の一部です。コンパイラがすべてを単独で行った場合、関数の 1 つのバージョンで C 配列定義の関数を使用できますが、次のバージョンではコンパイラ エラーが発生する可能性があります。より満足。

4

4 に答える 4

5

constexpr何かについてのコンパイラへの「ヒント」ではありません。constexpr必要です。コンパイル時に式を実際に実行する必要はありません。それができることが必要です。

(関数に対して) 行うことconstexprは、可能な限りコンパイル時にコンパイラがそのコードを簡単に実行できるように、関数定義に入れることができるものを制限することです。これは、プログラマーとコンパイラーの間の契約です。関数が契約に違反すると、コンパイラはすぐにエラーになります。

コントラクトが確立されるとconstexpr、言語がコンパイル時の定数式を必要とする場所でこれらの関数を使用できるようになります。次に、コンパイラは定数式の要素をチェックして、式内のすべての関数呼び出しが関数を呼び出していることを確認できconstexprます。そうでない場合は、再びコンパイラ エラーが発生します。

これを暗黙的にしようとすると、2 つの問題が発生します。constexprまず、言語で定義された明示的な契約がなければ、関数で何ができて何ができないかをどうやって知るのでしょうか? 関数を にしないものをどのように知ることができconstexprますか?

次に、関数を作成するという私の意図の宣言を介して、コントラクトがコンパイラにない場合constexpr、コンパイラは関数がそのコントラクトに準拠していることをどのように検証できますか? できませんでした。実際には適切なconstexpr関数ではないことがわかる前に、定数式で使用するまで待つ必要があります。

契約は、明示的に前もって述べておくのが最善です。

于 2013-07-15T18:16:20.860 に答える
3

constexpr は、指定された式をコンパイル時に評価できるかどうかを確認し、可能であればそうするためのコンパイラへのヒントと見なすことができます。

いいえ、以下を参照してください

最終的な目標はコンパイル時の評価です

いいえ、以下を参照してください。

では、可能な場合は、式ごとに実行してコンパイル時に評価しないのはなぜですか?

オプティマイザーは、as-if ルールで許可されているように、そのようなことを行います。

constexpr処理を高速化するために使用されるのではなく、ランタイム変数の式が不正であるコンテキストで結果を使用できるようにするために使用されます。

于 2013-07-15T18:22:43.560 に答える
2

これは私の評価にすぎませんが、(b) の理由は正しいと思います (コンパイラが強制できるインターフェイスの一部を形成するため)。インターフェイス要件は、コードの作成者とコードのクライアントの両方に役立ちます。

作成者は、コンパイル時のコンテキストで何かを使用できるようにすることを意図している可能性がありますが、実際にはこのように使用していません。ライターが のルールに違反した場合、constexprそれを使用しようとしたクライアントがconstexpr失敗したときに、発行後までわからない可能性があります。または、より現実的には、ライブラリがconstexprバージョン 1 である意味でコードを使用し、バージョン 2 でこの使用法をリファクタリングしconstexpr、バージョン 3 で気付かずに互換性を壊す可能性があります。constexpr-compliance にチェックを入れることで、バージョン 3 での不具合をデプロイ前にキャッチします。

クライアント用のインターフェイスはより明白です --- インライン関数が暗黙のうちに必須になることはありませんconstexpr

あなたの(a)理由(コンパイラには時間がかかりすぎる可能性がある)が当てはまるとは思いません.(1)constexprコードがマークされているとき、コンパイラはとにかく制約の多くをチェックしなければならない.(2)注釈なし.コンパイラは、ある意味で使用された場合にのみチェックを行う必要がありconstexprます (したがって、ほとんどの関数はチェックする必要がありません)。(3) IIUC Dプログラミング言語では、要件を満たしている場合、実際に関数をコンパイル時に評価できます。宣言の支援なしで、明らかにそれを行うことができます。

于 2013-07-15T18:06:36.423 に答える