10

インクルードガードが存在する理由を知っていますが、それ#pragma onceは標準ではないため、すべてのコンパイラなどでサポートされていません.

私の質問は別の種類のものです:

それらを持っていない合理的な理由はありますか?理論的には、別の場所に含めることを意図したファイルにインクルード ガードを提供しないことの利点があるという状況にまだ遭遇していません。それらを持たないことの実際の利点がある例を誰かが持っていますか?

私が尋ねる理由-私には、あなたがいつもそれらを使用しているので、それらはかなり冗長に見えます. の動作は#pragma once文字通りすべてに自動的に適用されるだけです.

4

6 に答える 6

11

インクルード前に定義されたマクロに応じてコードを生成するヘッダーを見てきました。この場合、それらのマクロを 1 つの (セットの) 値に定義し、ヘッダーをインクルードし、マクロを再定義し、再度インクルードすることが必要になる場合があります。
そのようなものを見た人は誰でも、それは醜く、避けるのが最善であることに同意しますが、(前述のヘッダーのコードが他の方法で生成された場合のように) それを行う方が悪いことではありません。

それ以外に理由が思い浮かびません。

于 2011-03-04T08:46:07.297 に答える
6

@sbi は既にコード生成について話しているので、例を挙げましょう。

多くの項目の列挙があり、その要素ごとに一連の関数を生成したいとします...

1 つの解決策は、この複数の包含のトリックを使用することです。

// myenumeration.td
MY_ENUMERATION_META_FUNCTION(Item1)
MY_ENUMERATION_META_FUNCTION(Item2)
MY_ENUMERATION_META_FUNCTION(Item3)
MY_ENUMERATION_META_FUNCTION(Item4)
MY_ENUMERATION_META_FUNCTION(Item5)

次に、人々はそれを次のように使用します。

#define MY_ENUMERATION_META_FUNCTION(Item_) \
  case Item_: return #Item_;

char const* print(MyEnum i)
{
  switch(i) {
    #include "myenumeration.td"
  }

  __unreachable__("print");
  return 0; // to shut up gcc
}

#undef MY_ENUMERATION_META_FUNCTION

これが良いかハックかはあなた次第ですが、列挙型に新しい値が追加されるたびにすべてのユーティリティ関数をクロールする必要がないことは明らかです。

于 2011-03-04T09:28:04.767 に答える
4
<cassert>
<assert.h>

「<assert.h>が含まれるたびに、NDEBUGの現在の状態に従ってassertマクロが再定義されます。」

于 2011-03-04T08:56:49.167 に答える
0

プロジェクトに同じインクルード ガードを使用する 2 つのヘッダーがある場合、問題になる可能性があり__CONSTANTS_H__ます。#include特定のコンパイル単位で両方のヘッダーを正常に処理できます。より良い解決策は です#pragma onceが、一部の古いコンパイラはこれをサポートしていません。

于 2011-03-04T08:49:03.147 に答える
0

サードパーティのライブラリがあり、そのコードを変更できないとします。このライブラリからファイルをインクルードすると、コンパイラの警告が生成されるとします。通常、独自のコードを高い警告レベルでコンパイルすることをお勧めしますが、そうすると、ライブラリの使用によって大量の警告が生成されます。サードパーティのライブラリをラップできる警告の無効化/有効化ヘッダーを記述でき、それらを複数回含めることができるはずです。

もう 1 つのより洗練された使用法は、Boost のプリプロセッサ反復構造です: http://www.boost.org/doc/libs/1_46_0/libs/preprocessor/doc/index.html

于 2011-03-04T08:52:14.767 に答える
-1

#pragma once の問題、およびそれが標準の一部ではない理由は、常にどこでも機能するとは限らないことです。異なるパスから含まれている場合、コンパイラは 2 つのファイルが同じファイルであるかどうかをどのように認識しますか?

考えてみてください。コンパイラが間違いを犯して、インクルードすべきファイルをインクルードできなかった場合はどうなるでしょうか? あるべきではないファイルを 2 回インクルードするとどうなりますか? どうやってそれを修正しますか?

インクルード ガードを使用すると、コンパイルに時間がかかるという最悪の事態が発生します。

編集: comp.std.c++ のこのスレッド「#pragma once in ISO standard yet?」を確認してください。

http://groups.google.com/group/comp.std.c++/browse_thread/thread/c527240043c8df92

于 2011-03-04T17:47:33.970 に答える