C++には(生成された)リテラル文字列があり、\x
表記を使用してエスケープする必要のある文字を含めることができます。例えば:
char foo[] = "\xABEcho";
ただし、g ++(問題がある場合はバージョン4.1.2)はエラーをスローします。
test.cpp:1: error: hex escape sequence out of range
コンパイラは、Ec
文字を先行する16進数の一部と見なしているようです(16進数のように見えるため)。 4桁の16進数はchar
に収まらないため、エラーが発生します。明らかに、ワイド文字列リテラルL"\xABEcho"
の場合、最初の文字はU + ABECで、その後にL"ho"
が続きます。
これは過去数十年の間にいつか変わったようで、私は気づかなかった。古いCコンパイラは\x
の後の2 16進数のみを考慮し、それ以上は検討しないとほぼ確信しています。
これに対する1つの回避策を考えることができます。
char foo[] = "\xAB""Echo";
しかし、それは少し醜いです。だから私は3つの質問があります:
これはいつ変更されましたか?
コンパイラがワイド文字列リテラルで2桁を超える16進エスケープしか受け入れないのはなぜですか?
上記より扱いにくい回避策はありますか?
私の質問に対する答えを見つけました:
C++は常にこのようにしてきました(Stroustrupの第3版を確認しましたが、以前はありませんでした)。 K&R 1st editionは\x
についてまったく言及していませんでした(その時点で使用可能な唯一の文字エスケープは8進数でした)。 K&R第2版は次のように述べています。
'\xhh'
ここでhhは1つ以上の16進数字(0 ... 9、a ... f、A ... F)です。
したがって、この動作はANSI C以降に発生しているようです。
コンパイラーは、ワイド文字列リテラルとして2文字以上しか受け入れられない可能性がありますが、これにより文法が不必要に複雑になります。
実際、それほど厄介な回避策はありません。
char foo[] = "\u00ABEcho";
\u
エスケープは、常にfour16進数を受け入れます。
更新:ほとんどのASCII文字は(何らかの理由で)を使用して指定することが許可されていないため、\u
\u
。GCCからの抜粋です:
/* The standard permits $, @ and ` to be specified as UCNs. We use
hex escapes so that this also works with EBCDIC hosts. */
else if ((result < 0xa0
&& (result != 0x24 && result != 0x40 && result != 0x60))
|| (result & 0x80000000)
|| (result >= 0xD800 && result <= 0xDFFF))
{
cpp_error (pfile, CPP_DL_ERROR,
"%.*s is not a valid universal character",
(int) (str - base), base);
result = 1;
}
これを解決するには、次の文字も\ xnnで指定します。残念ながら、[a..f]の範囲にcharがある限り、これを使用する必要があります。例。 「\ xnneceg」は「\ xnn\x65\x63\x65g」に置き換えられます
C++は常にこのようになっていると確信しています。とにかく、 CHAR_BIT
は8より大きい場合があります。その場合、'\xABE'
または'\xABEc'
は有効である可能性があります。