このウィキペディアのページでは、C++を「空白に依存しない言語」として定義しています。すべての言語と同様にほとんど真実ですが、規則には例外があります。現時点で私が考えることができるのはこれだけです:
vector<vector<double> >
スペースが必要です。スペースがない場合、コンパイラは>>をストリーム演算子として解釈します。他に何がありますか。例外のリストを編集するのは興味深いでしょう。
このウィキペディアのページでは、C++を「空白に依存しない言語」として定義しています。すべての言語と同様にほとんど真実ですが、規則には例外があります。現時点で私が考えることができるのはこれだけです:
vector<vector<double> >
スペースが必要です。スペースがない場合、コンパイラは>>をストリーム演算子として解釈します。他に何がありますか。例外のリストを編集するのは興味深いでしょう。
その論理に従って、任意の2文字の語彙素を使用して、ルールに対するそのような「例外」を生成できます。たとえば、+=
と+ =
は別の方法で解釈されます。しかし、私はそれらを例外とは呼びません。多くのコンテキストでのC++では、「スペースがまったくない」と「1つ以上のスペース」はまったく異なります。C ++がスペースに依存しないと誰かが言うとき、彼らは通常、C++の「1つのスペース」が通常「複数のスペース」と同じであることを意味します。
これは、翻訳のフェーズ3で、実装が複数の空白文字のシーケンスを1つのスペース文字に置き換えることができると述べている言語仕様(2.1 / 1を参照)に反映されています。
C ++を解析するための構文規則とセマンティック規則は、確かに非常に複雑です(私は、「混乱」と言うことを許可されていると思います)。この事実の証拠は、何年もの間、合法的なC ++とそうでないものについて議論している、さまざまなコンパイラの作成者であるということです。
たとえば、C ++では、最初のトークンの意味を決定する前に、無制限の数のトークンを解析する必要がある場合があります(これは、多くの場合、新規参入者を噛む恐ろしい「最も厄介な解析ルール」です)。
ただし、異議申し立てIMOは実際には意味がありません...たとえば、と++
は異なる意味を+ +
持ち、Pascalでは。begin
と同じではありませんbeg in
。これにより、Pascalはスペースに依存する言語になりますか?スペースに依存しない言語(brainf * ckを除く)はありますか?
C ++ 03 >>
/に関する唯一の問題> >
は、入力時のこの間違いが非常に一般的であったため、C ++ 11でこの問題を解決するために、言語定義をさらに複雑にすることにしました。
> >
より多くの空白の代わりに1つの空白が違いを生む可能性がある場合(スペースに依存する言語を区別するものであるが、 /の場合には何の役割も果たさない>>
もの)は確かに少数です。
二重引用符で囲まれた文字列の内部(ただし、誰もがそれを望んでおり、私が知っている文字列リテラルをサポートするすべての言語が同じことをします)
一重引用符の中に(同じですが、多くのC ++プログラマーが知らないことは、一重引用符の中に複数の文字が存在する可能性があるということです)
プリプロセッサディレクティブでは、行ベースで機能するためです(改行は空白であり、そこで違いが生じます)
stefanvが気付いた行の継続:1行を継続するには、改行の直前にバックスラッシュを置くことができます。その場合、言語は両方の文字を無視します(通常の使用法であっても、識別子の途中でもこれを行うことができます)長いプリプロセッサマクロを読み取り可能にするためだけです)。バックスラッシュの後、改行の前に他の空白文字を配置すると、行の継続は認識されません(いずれにせよ、一部のコンパイラはそれを受け入れ、行の最後の非空白がバックスラッシュであるかどうかをチェックします)。行の継続は??/
、バックスラッシュに相当するトリグラフを使用して指定することもできます(トリグラフがプログラマーによってインデントされていない可能性が高いため、IMOがトリグラフを見つけるときに警告を発する必要があります)。
//
コメントの途中で他の空白に改行を追加すると違いが生じるため、単一行コメント内
好むと好まざるとにかかわらず、マクロもC ++の一部であり、複数行のマクロはバックスラッシュとそれに続くEOLで区切る必要があり、バックスラッシュとEOLの間に空白を入れないでください。
大きな問題ではありませんが、それでも空白の例外です。
set<set<int> >
。' '
。" "
。else return x;
などvoid foo(){}
。これは、c++11より前のパーサーの制限のためです。これはもはや当てはまりません。
その理由は、演算子>>と比較してテンプレートの終わりとして>>を解析するのが困難だったためです。
C ++ 03はすべての場合にシフト演算子として解釈>>
しましたが(ストリームで使用するためにオーバーライドされましたが、それでもシフト演算子です)、C ++ 11の言語パーサーは、妥当な場合に中括弧を閉じようとします。