4

たとえば、システム固有の関数を使用する必要があります( POSIX標準に従ってftello()定義されています)。stdio.hまた、標準の C++ 機能も使用する必要があります。たとえば、 ( ISO C++ 標準に従ってstd::sprintf()で定義されています)。cstdio

私の知る限り、非標準 C++ のものを定義するだけで<cstdio>は保証されないため、両方を含める必要があると思います。私はずっと前に、(たとえば) gcc ではインクルード ファイルの順序に問題がある可能性があることを読みました。

<cstdio>では、 と の両方を含める正しい順序は何<stdio.h>ですか? 可能な限りクロスプラットフォームのソリューションを探しています (少なくとも gcc、suncc、intel C++/linux、および mingw の場合)。

4

6 に答える 6

2

本当のルールはわかりませんが、一般的に言えば、上位レベルのライブラリの前に下位レベルのシステムライブラリを含めます。

したがって、この場合、stdio.hはCヘッダーであり、(私の想像では)マシンに近く、<cstdio>より高レベルのC ++標準ライブラリであり、より抽象化されていると思います。

stdio.h私は自分の前に含める傾向がありますがcstdio、その論理的根拠を支持する正確な理由はわかりません。

于 2009-06-22T00:47:50.823 に答える
2

OK、さらに調査した結果、最初に C++ ヘッダーをインクルードし、C ヘッダーを後でインクルードするのが正しいという結論に達しました。たとえば、次の C++0x ヘッダー (gcc から) を考えてみましょう。

/usr/include/c++/4.3/tr1_impl/cstdint:


// ...
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include_next <stdint.h>
// ...

これが行うことは、2 つの C99 マクロを定義してから、C99 stdint.h ヘッダーをインクルードすることです。その理由は、C99 では stdint.h の一部の機能がオプションであり、それらのマクロが定義されている場合にのみ使用できるためです。ただし、C++0x では、すべての stdint.h 機能が必須です。ここで、最初に C99 の stdint.h を含め、後で cstdint を含めた場合、stdint.h のヘッダー ガードのために、必須の C++0x 機能を取得できません。これはコンパイラのベンダーのせいだと主張する人もいるかもしれませんが、それは正しくありません。stdint.h はシステムにバンドルされたヘッダー (この場合は glibc から) であり、これは C99 ヘッダーであり、C++0x (結局のところ古いシステムである可能性があります) または gcc については何も知りません。コンパイラは実際にはすべてのシステム ヘッダーを修正することはできませんが (この場合、C++ モードでこれらの機能を常に有効にするため)、これらのシステムで C++0x サポートを提供する必要があります。

于 2009-07-18T13:30:49.880 に答える
2

システム ヘッダー ファイルの場合、通常、インクルードの順序がエラーの原因になることはありません。

他のヘッダー ファイルについては、SO で同様の質問をご覧ください

于 2009-06-21T10:50:34.980 に答える
0

最も具体的なものを一番上に置き、最も具体的でないものを一番下に置きます。たとえば、ソースファイルの場合は次のようになります。

  1. プリコンパイル済みヘッダー(ある場合)
  2. このソースファイルのヘッダー
  3. プロジェクトに含まれるもの
  4. 最も具体的なライブラリ、たとえばこのプロジェクトのライブラリ、または企業ライブラリ
  5. Boostのような「システム」ライブラリやSDLなどの最も特定性の低いライブラリ
  6. 標準C++
  7. 標準C
  8. オペレーティングシステムヘッダー

私の正当な理由は、より具体的なヘッダーにはより一般的なヘッダーが含まれることが多く、マクロを介してそれらを変更したいということです。これらがすでに含まれている場合は、ガードを含めるか、デフォルトのマクロ値がシステムライブラリの動作を妨害します。

もう1つの理由は、この順序により、他のヘッダーから依存関係を「隠す」ことができないことです。つまり、他のソースファイルからインクルードされた場合、それらのヘッダーは常にシステムライブラリが含まれているため、スタンドアロンにはなりません。

于 2009-10-22T09:56:40.660 に答える
0

私が知る限り、ftello() と sprintf() はどちらも stdio.h に含まれています。

非標準ヘッダーではインクルード順序が重要になる場合があります。依存構造をチェックして、どれが他に依存しているかを調べ、正しい順序でインクルードする必要があります。

このため、インクルード ファイルの依存関係はインクルード ファイルに含める必要があり、それらが適切に含まれていることを確認するために「ユーザー」に依存しないでください。

于 2009-06-21T10:51:55.337 に答える
0

あなたは正当な理由もなく心配しています。の内容は、 (17.4.1.2 Headers/4)の内容を<cstdio>「含めるかのように」です。<stdio.h>ただし、宣言と定義 (マクロのものではない) は名前空間 std にあります。

したがって、書く必要があるかもしれませんstd::ftello()。移植性を向上させるために、ausing std::ftello;を入れれば、それも気にする必要はありません。

于 2009-06-22T09:58:10.263 に答える