9

私は現在、CS コースの最終試験のために勉強していて、C++ #ifndef の構文に関するマイナーな (おそらくメジャーな?) 問題に遭遇しました。

#infndef を #include ガードとして使用する場合の構文を見てきましたが、Web 上のほとんどは次のように言っているようです。

#ifndef HEADER_H
#define "header.h"
...
#endif

しかし、私のクラスのチュートリアル スライドでは、例を次のように示しています。

#ifndef __HEADER_H__
#define "header.h"
...
#endif

私は、2つの違いが(もしあれば)何であるか疑問に思っていました。試験では #include ガードを書くように求められる可能性が高く、教授や家庭教師の言うことに従うのが一般的な通念であることはわかっていますが、コンパイル中に違いがある場合は知りたいです。

4

4 に答える 4

18

通常はどちらも実行せず、インクルード ガードをヘッダー ファイルに配置します。繰り返しを減らすためです。例えば:

header.h

#ifndef HEADER_H
#define HEADER_H

// Rest of header file contents go here

#endif

マクロ名として正確に何を使用するかは、特定のコーディング標準に依存します。ただし、C および C++ 標準には、アンダースコアで始まる識別子を使用できないようにするさまざまな微妙な規則があります1__HEADER_H__

また、コードベース内の他のものと衝突する可能性が低いものを選択する必要があることにも言及する価値があります。たとえば、たまたま別のHEADER_H場所で呼び出された変数がある場合 (ありそうもないことだと思います)、腹立たしいエラーが発生することになります。


1. たとえば、C99 標準のセクション 7.1.3 を参照してください。

于 2012-04-09T17:21:36.477 に答える
5

2 つのアンダースコアで始まる名前は実装用に予約されているため、__SOMETHINGインクルード ガードでは使用しないことをお勧めします。また、衝突が起こりにくい名前を選択するようにしてください。したがって、あなたのクラスのチュートリアルは、少なくとも 2 つの点で間違っているようです。たとえば、このユーモラスな記事を参照してください。

于 2012-04-09T17:25:58.347 に答える
1

ヘッダー自体ではなく、ヘッダーをインクルードするファイルにインクルード ガードを配置する理由は、ファイルが既にインクルードされている場合、コンパイラ (特にプリプロセッサ) がインクルード ファイルを開いて再度読み取る必要がないことです。 .

それは弱い議論です。実際には、節約される時間はわずかであり、エラーの可能性は大きくなります。

あなたの例では:

#ifndef HEADER_H
#include "header.h"
...
#endif

あなたは私たちに を見せません#define HEADER_H。のどこかにありheader.hますか? もしそうなら、の作者がインクルード ガード マクロの名前としてheader.h使用することを選択したことをどのように知ることができますか? HEADER_H後で別のものに変更した場合はどうなりますか?

インクルード ファイルにインクルード ガードを配置する場合は、そこにもマクロを定義する必要があります

#ifndef HEADER_H
#include "header.h"
#define HEADER_H
#endif

しかし、他の回答がすでに述べているように、ヘッダー自体にガードを配置する方がはるかに優れています。

header.h :

#ifndef HEADER_H
#define HEADER_H
/* contents of header.h */
#endif

そして、インクルードには次のものがあります。

#include "header.h"

心配する情報が 1 つ少なくなります。

于 2012-04-09T17:35:47.057 に答える
1

他の場所で変数名にアンダースコアを使用しなくても違いはありません。それは単なる命名規則です。

ユニークなものを入れるだけです。

于 2012-04-09T17:23:20.950 に答える