web-dev-qa-db-ja.com

名前空間内の#defineステートメント

そのような名前空間内に#defineステートメントがある場合:

namespace MyNamespace
{
  #define SOME_VALUE 0xDEADBABE
}

#defineステートメントは名前空間に限定されないというのは正しいですか?

次は「正しい」ことですか?

namespace MyNamespace
{
  const unsigned int SOME_VALUE = 0xDEADBABE;
}
48
Soo Wei Tan

正解です。#defineは名前空間に拘束されません。 #defineプリプロセッサ ディレクティブです。コンパイラを介してコンパイルされる前にソースファイルが操作されます。名前空間はコンパイル手順中に使用され、コンパイラーは#defineについての洞察を持ちません。

プリプロセッサはできるだけ避けてください。このような定数値の場合、#defineよりもconstを優先します。

62
Michael

定数の使用と#definesのスコープの制限がないという提案に完全に同意します。

ただし、 行う プリプロセッサ#define行を使用する必要があります。予想されるスコープに合わせて正しくカバーしてください。

namespace MyNamespace
{
  #define SOME_VALUE 0xDEADBABE
  // your code
  #undef SOME_VALUE
}

なぜ#defines
組み込みプラットフォームがコードの定数をサポートしなかった1つのケースを知っています。
初期化する方法がありませんでした...
常に読みやすくするのに役立ちます。

20
nik

プリプロセッサは、名前空間やその他の言語レベルの概念が「キックイン」する前に(概念的には少なくとも、実際には多くの場合も)動作します。つまり、はい、言語レベルの構成を使用するほうが間違いなく多く優れています可能な限りconst値など!

4
Alex Martelli

はい。一般に、#defineされた値の代わりにconst値を使用すると、多くの利点があります。変数のスコープを制限することは、利点の1つです。スコープは、ネームスペース、またはこの方法(クラスレベル、関数レベルなどを含む)の他の有効なスコープに制限できます。

3
Reed Copsey

何らかの理由で2番目のケースに変更できなかった場合、MyNamespaceを独自のオブジェクトにコンパイルしてオブジェクトを個別にリンクする(または、おそらくその単一の名前空間でプリプロセッサを実行する)必要があると確信しています単独で)。 C++プリプロセッサは#defineステートメントを受け取り、基本的に文字列置換anywhereを実行する必要があります。これは、SOME_VALUEがソースコードに表示されることを意味します。したがって、プリプロセッサが#defineを認識していない場合、SOME_VALUEを別のソースファイルで置き換えることはできません。

0
Mark Rushakoff