30

私はこのようなC++コードに出くわしました:

int $T$S;

最初は、ある種のPHPコードか、そこに間違って貼り付けられたものだと思いましたが、コンパイルと実行は正常に行われました(MSVC2008)。

C ++の変数にはどのような文字が有効ですか?他に使用できる奇妙な文字はありますか?

4

4 に答える 4

33

標準に準拠した唯一の有効な文字は、英数字とアンダースコアです。この規格では、Unicodeがアルファベットと見なすほぼすべてのものが受け入れ可能である必要があります(ただし、単一のコードポイント文字としてのみ)。実際には、実装は拡張機能(つまり、$を受け入れるものもあります)と制限(ほとんどの場合、必要なUnicode文字のすべてを受け入れるわけではありません)を提供します。コードを移植可能にする場合は、記号をアクセント記号のない26文字、大文字または小文字、10桁、および「_」に制限します。

于 2011-10-28T07:48:03.513 に答える
14

これは一部のコンパイラの拡張であり、C標準にはありません

MSVC:

Microsoft固有

MicrosoftC++識別子の最初の2048文字のみが重要です。ユーザー定義型の名前は、型情報を保持するためにコンパイラーによって「装飾」されます。タイプ情報を含む結果の名前は、2048文字を超えることはできません。(詳細については、装飾名を参照してください。)装飾識別子の長さに影響を与える可能性のある要因は次のとおりです。

  • 識別子がユーザー定義型のオブジェクトを表すか、ユーザー定義型から派生した型を表すか。
  • 識別子が関数を表すか、関数から派生した型を表すか。
  • 関数への引数の数。

ドル記号は、VisualC++でも有効な識別子です。

// dollar_sign_identifier.cpp
struct $Y1$ {
    void $Test$() {}
};

int main() {
    $Y1$ $x$;
    $x$.$Test$();
}

https://web.archive.org/web/20100216114436/http://msdn.microsoft.com/en-us/library/565w213d.aspx

最新バージョン:https ://docs.microsoft.com/en-us/cpp/cpp/identifiers-cpp?redirectedfrom = MSDN&view = vs-2019

GCC:

6.42識別子名のドル記号

GNU Cでは、通常、識別子名にドル記号を使用できます。これは、多くの従来のC実装がそのような識別子を許可しているためです。ただし、識別子のドル記号は、通常、ターゲットアセンブラで許可されていないため、一部のターゲットマシンではサポートされていません。

http://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar-Signs

于 2013-08-03T14:39:28.510 に答える
2

私の知る限り、文字(大文字と小文字)、数字09)、および_標準に従った変数名にのみ有効です(注:変数名は数字で始めることはできません)。

他のすべての文字はコンパイラ拡張である必要があります。

于 2011-10-28T07:48:22.843 に答える
0

これは良い習慣ではありません。通常、識別子には英数字とアンダースコアのみを使用する必要があります([a-z][A-Z][0-9]_)。

表面レベル

他の言語(bash、perl)とは異なり、Cは$変数の使用法を示すために使用しません。そのため、技術的に有効です。Cでは、C11、6.4.2に該当する可能性があります。これは、最新のコンパイラでサポートされているように見えることを意味します。

C ++の質問については、テストしてみましょう。

int main(void) {
    int $ = 0;
    return $;
}

GCC / G ++ / Clang / Clang ++では、これは確かにコンパイルされ、問題なく実行されます。

より深いレベル

コンパイラーはソースコードを受け取り、それをトークンストリームに入れ、それを抽象構文木(AST)に入れ、それを使用してコードを生成します(例:アセンブリ/ LLVMIR)。あなたの質問は実際には最初の部分(例えば字句解析)を中心に展開します。

C / C ++の文法(したがってレクサーの実装)は$、コンマ、ピリオド、細い矢印などとは異なり、特別なものとしては扱われません。そのため、以下のcコードから次のようなレクサーからの出力を取得できます。

int i_love_$ = 0;

レクサーの後、これは次のようなトークンスチームになります。

["int", "i_love_$", "=", "0"]

このコードをどこで取得するか:

int i_love_$,_and_.s = 0;

レクサーは次のようなトークンスチームを出力します:

["int", "i_love_$", ",", "_and_", ".", "s", "=", "0"]

ご覧のとおり、C / C ++は$のような文字を特殊なものとして扱わないため、ピリオドのような他の文字とは異なる方法で処理されます。

于 2021-07-15T03:51:40.623 に答える