C ++では、なぜ__(ダブルアンダースコア)をそれほど多く使用するのですか?


93

私はいくつかのオープンソースのC ++コードを調べていましたが、コードで使用されているスコアの下で、主に変数名の最初に多くの二重のスコアがあることに気付きました。

return __CYGWIN__;

これには理由があるのでしょうか、それとも単に一部の人々がコードスタイルをコーディングしているのでしょうか。読みにくくしていると思います。


2
なぜ読みにくいのですか?それは引用符のように、ほとんどが区切り文字として設計されています。私が覚えているように、それは主に組み込み定数に使用されます。
Matthew Scharley、2008年

1
いいえ、区切り文字ではありません。下線は、実装用に予約されている名前とユーザーのソースコードが使用できる名前を区別するために使用されます。ユーザーが行うことができます#define FOO 1が、彼らはありませんしてはならない#define __FOO__ 1ので、実装が名前を自由に使用する__FOO__独自のマクロ、変数、関数などのために
ジョナサンWakely

私はマシューがそれを機能的にではなく、スタイル/視覚的にデリミタであることを意味したと思います。これは興味深い仮説ですが、私が以前読んだこととジョナサンの答えを考えると正しくありません。
JMIマディソン

回答:


127

C ++でのプログラミングから、ルールと推奨事項

識別子での2つのアンダースコア( `__ ')の使用は、ANSI-C標準に従って、コンパイラの内部使用のために予約されています。

下線( `_ ')は、ライブラリ関数(" _main "や" _exit "など)の名前でよく使用されます。衝突を避けるために、識別子をアンダースコアで始めないでください。


1
そのガイドnamespaceは、導入前に書かれたように見えます。
cz

また、C ++標準からではなく、帝国大学ロンドンからのものでした。それは良い提案かもしれません。
stucash

1
@cz名前空間は無関係です。システムヘッダーは、アンダースコアで始まるマクロ名を定義できます_main
martinkunev

49

彼らが「実装の一部」、つまり標準ライブラリであると感じない限り、そうすべきではありません。

ルールはかなり具体的であり、他の一部が提案しているよりも少し詳細です。

2つのアンダースコアを含む、またはアンダースコアで始まり、その後に大文字が続くすべての識別子は、すべてのスコープでの実装の使用のために予約されています。つまり、それらはマクロに使用される可能性があります。

さらに、アンダースコアで始まる他のすべての識別子(つまり、別のアンダースコアまたは大文字が後に続かない)は、グローバルスコープでの実装用に予約されています。つまり、これらの識別子を独自の名前空間またはクラス定義で使用できます。

これが、MicrosoftがC ++標準に含まれていないコアランタイムライブラリ関数の多くに、先頭に下線を付け、すべて小文字の関数名を使用する理由です。これらの関数名は、標準のC ++関数またはユーザーコード関数と競合しないことが保証されています。


1
C ++では、[lex.name]とグローバル名[global.names]のみが表示されます。参考にしていただけますか?ありがとう
a.lasram 2014年

36

C ++標準によると、1つのアンダースコアで始まる識別子はライブラリ用に予約されています。2つのアンダースコアで始まる識別子は、コンパイラベンダー用に予約されています。


18
それ以上:ダブルアンダースコアを含む識別子は予約されています。17.4.3.1.2
スティーブジェソップ

C ++では、[lex.name]とグローバル名[global.names]のみが表示されます。参考にしていただけますか?ありがとう
a.lasram 2014年

10

上記のコメントは正しいです。 __Symbol__通常は、役立つコンパイラ(またはプリプロセッサ)ベンダーから提供されるマジックトークンです。おそらく、これらの中で最も広く使用されているのは__FILE__and __LINE__であり、Cプリプロセッサによって展開され、現在のファイル名と行番号を示します。これは、エラーのテキストによる場所を含め、何らかのプログラムアサーションエラーをログに記録する場合に便利です。


8

これは、「通常の」コードで行うことを意図したものではありません。これにより、コンパイラとシステムライブラリが、自分のものと衝突しないシンボルを定義できるようになります。


5

ダブルアンダースコアは実装に予約されています

上位投票の回答は、C ++でのプログラミング:ルールと推奨事項を引用しています。

「識別子での2つのアンダースコア( `__ ')の使用は、ANSI-C標準に従って、コンパイラーの内部使用のために予約されています。」

しかし、いくつかのC ++およびC標準を読んだ後、アンダースコアがコンパイラーの内部使用のみに制限されていることに言及することはできませんでした。標準はより一般的で、実装のために2つのアンダースコアを予約していますます。

C ++

C ++(現在作業中のドラフト、2019-5-26にアクセス)は次のように述べていlex.nameます:

  • 二重下線__を含む、またはアンダースコアで始まり、その後に大文字が続く各識別子は、使用のために実装用に予約されています。
  • アンダースコアで始まる各識別子は、グローバル名前空間の名前として使用するために実装に予約されています。

C

この質問はC ++に固有のものですが、C標準99および17の関連セクションを引用しました。

C99セクション7.1.3

  • アンダースコアで始まるすべての識別子と、大文字または別のアンダースコアは、常に使用のために予約されています。
  • アンダースコアで始まるすべての識別子は、通常の名前空間とタグ名前空間の両方で、ファイルスコープを持つ識別子として使用するために常に予約されています。

C17はC99と同じことを言っています。

実装とはですか?

C / C ++の場合、実装は大まかにユーザーソースファイルから実行可能ファイルを生成するために必要なセットリソースを指します。これも:

  • プリプロセッサ
  • コンパイラ
  • リンカ
  • 標準ライブラリ

実装例

ウィキペディアで言及されているさまざまなC ++実装がいくつかあります。(アンカーリンクなし、ctrl + f "実装")

以下に、Digital MarsのC / C ++実装の例を示します。これらの機能のためにいくつかのキーワードが予約されています。


3

他の多くの人々が回答したライブラリに加えて、一部の人々は、プリプロセッサで使用するためにマクロまたは#define値に名前を付けます。これにより、操作が簡単になり、古いコンパイラのバグを回避できる場合があります。

他の人が述べたように、名前の衝突を防ぎ、ライブラリ変数と自分の変数を区別するのに役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.