Cおよび C++ 標準にはすべて、文字列化操作が有効な文字列リテラル トークンの生成に失敗した場合の動作が未定義であるという趣旨のテキストが含まれています。C++11 では、生の文字列リテラルに改行文字を含めることで、これが実際に可能です。しかし、キャッチオールは常に標準に含まれています。
UBまたは不正な形式のプログラムがまだ発生していない場合に、stringizeがUBを生成できる他の方法はありますか?
Cや C++の方言について聞きたいです。私はプリプロセッサを書いています。
Cおよび C++ 標準にはすべて、文字列化操作が有効な文字列リテラル トークンの生成に失敗した場合の動作が未定義であるという趣旨のテキストが含まれています。C++11 では、生の文字列リテラルに改行文字を含めることで、これが実際に可能です。しかし、キャッチオールは常に標準に含まれています。
UBまたは不正な形式のプログラムがまだ発生していない場合に、stringizeがUBを生成できる他の方法はありますか?
Cや C++の方言について聞きたいです。私はプリプロセッサを書いています。
stringify ( ) 演算子は、文字列定数で#
のみエスケープします。\
実際、\
行末を除いて、文字列定数の外では特に意味はありません。したがって、これは前処理トークンです (C セクション 6.4、C++ セクション 2.5)。
したがって、
#define Q(X) #X
それから
Q(\)
は正当な呼び出し\
です。これは、トークンに変換されることのない前処理トークンであるため、有効です。しかし、文字列化することはできません\
。有効な文字列リテラルではない「\」が表示されます。したがって、上記の動作は未定義です。
これはもっと面白いテストケースです:
#define Q(A) #A
#define ESCAPE(c) Q(\c)
const char* new_line=ESCAPE(n);
const char* undefined_behaviour=ESCAPE(x);
未定義の文字列化のあまり興味深いケースは、文字列化されたパラメーターが長すぎて文字列リテラルにならない場合です。(標準では、文字列リテラルの最大サイズを少なくとも 65536 文字にすることを推奨していますが、マクロ引数の最大サイズについては何も述べていません。おそらくこれより大きくなる可能性があります。)