web-dev-qa-db-ja.com

なぜ人々はC ++で__(二重アンダースコア)をそれほど使用するのですか?

私はいくつかのオープンソースのC++コードを調べていましたが、主に変数名の先頭で、コード内で使用されているスコアの下に多くの二重アンダースコアがありました。

return __CYGWIN__;

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

85
Nathan W

C++でのプログラミング、規則と推奨事項 から:

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

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

119
maccullt

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

ルールはかなり具体的であり、他の一部が示唆しているよりもわずかに詳細です。

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

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

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

48
CB Bailey

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

34
James Curran

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

10
bog

「通常の」コードで行うつもりのないことです。これにより、コンパイラとシステムライブラリが、ユーザーのシンボルと衝突しないシンボルを定義できるようになります。

8
Menkboy

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

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

2
Sqeaky

トップ投票の回答は、引用 C++でのプログラミング:規則と推奨事項

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

ただし、そのページの主張はunfounded

私はいくつかのC++およびC標準を検索しましたが、下線がコンパイラの内部使用に制限されているという言及を見つけることができませんでした。

C++ (現在の作業ドラフト、2019-5-26にアクセス)Lex.name

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

TL; DR:二重アンダースコアは実装専用です

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

C99 セクション7.1.3

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

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

2