2017-07-09 3 views
4

私はいくつかのC/C++ソースファイルにcmakeのプロジェクト内のautotoolsのプロジェクトの一部を再利用していると私はのような行が散らばって多くのソースファイルを参照してください。私はgetpid()がオプションであればこの目的は、構築を理解するであろうHAVE_ *マクロの目的は何ですか?

#ifdef HAVE_UNISTD_H 
#include <unistd.h> // for getpid() 
#endif 

をその呼び出しは同等のHAVE_UNISTD_Hディレクティブで囲まれていました。ただし、HAVE_UNISTD_Hを指定しないと、ソースファイルはコンパイルされず、getpid()は定義されていません。これは、unistd.hが見つかりませんでしたことを私に知らせるコンパイラよりもはるかに秘密だと感じています。

もちろん、これは一例に過ぎません。その他の一般的なマクロには、HAVE_STDINT_H,HAVE_INTTYPES_Hなどがあります。ソースファイルをコンパイルするにはその存在が必須です。

なぜHAVE_*ガードが含まれていますか?私は、彼らが唯一の欠点を持って感じる:などのソースファイルを再利用

  • は、右のヘッダファイルがHAVE_*マクロが定義されてい右の存在を確認することが必要です。
  • 間違いの場合、開発者は根本的な原因(ヘッダーが見つかりません)を報告するのではなく、付随的なエラー(型/機能が見つかりません)を報告します。
  • ソースファイルは少し長めで、読むのが少し面倒です(#include#ifdefが混在しています)。
+1

これはCですか、C++ですか?ほとんどの現在のコンパイラのCのデフォルトモードは、 'getpid()'が宣言されていないことに関するエラーメッセージを出すものではありません。誰があなたに依頼するかに応じて、どちらがマクロの理由と反対かです。 – hvd

+0

https://stackoverflow.com/questions/1653958も参照してください。 –

+0

@hvd:バージョン5以降のGCCはデフォルトでC11モードに設定されており、暗黙的に宣言されている関数については警告メッセージを生成します。 GCCの古いバージョンだけがC90にデフォルト設定されています。 –

答えて

9

ほとんどのHAVE_xxx_hガードは、POSIXが来て、ヘッダファイルを標準化する前の時代の残党です。 90年代初頭には、の場合はgetpid()となりましたが、その機能は別のヘッダファイルで宣言されるか、まったく宣言されませんでしたが、それでも機能する場合があります返り値がi​​nt型の場合)、K & RおよびC89 Cでは宣言がオプションであったために、返されました。

当時使用されていた多数のシステム間にはさらに異例の問題がありました。たとえば、time.hを出荷したシステム、sys/time.hを出荷したシステム、および両方を出荷したシステムがありました。ただし、最後のカテゴリの中に実際に両方を組み込むと、コンパイルエラーが発生するサブセットがありました。可能であれば、それらをすべて前もってリストしなくても、膨大な数のこのようなシステムをサポートすることは、Autoconfの明白な設計目標の1つであり、長い無関係なハックのいくつかは依然としてcarefully documentedです。

上記の懸念に加えて、関数のサポートからヘッダー名を切り離すことは、コードをWindowsなどの非POSIXシステムに移植するときに役立ちます。そのようなシステムでは、posixヘッダーが見つからないか壊れている可能性があり、実際の関数定義はgnulibなどの移植性ライブラリからのものです。

+0

"の前のANSI Cでは宣言がオプションであるため - C89/C90も同様です。 – hvd

+0

@hvdありがとう、訂正しました。 C99とC11はどうですか? GCCは少なくとも、警告だけで宣言されていない関数を使用できるように思われます。 – user4815162342

+1

正式には、C99とC11では構文エラーです(プライマリ式を参照してください、脚注は明示的です)。コンパイラは構文的に無効なコードを拡張子として受け入れることができ、GCCは下位互換性のためにこれを行います。 TCCはそれだけで信じている)。 – hvd

1

なぜHAVE_ *ガードが含まれているのですか?私は彼らが欠点しか持っていないと感じます:...

ソースは別の実装に近づくことができます。その場合、間違ったインクルードのエラーを取得したくないことは確かです。

愚か例:

#ifdef HAVE_UNISTD_H 
#include <unistd.h> // for getpid() 
#endif 
#ifdef HAVE_WINDoWS_H 
#include <windows.h> // for GetProcessId() 
#endif 

私は窓がgetpid()をサポートしていることを知っています。

関連する問題