メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

トークン連結からのユニバーサル文字名

## 演算子でトークンを結合することによりユニバーサル文字列名を作成

説明

この欠陥は、## 演算子で結合された 2 つの前処理トークンによってユニバーサル文字名が作成された場合に発生します。ユニバーサル文字列名は \u または \U で始まり 16 進数の桁が続きます。これは基本文字セットで見つからない文字を表します。

たとえば、2 つのトークンを結合して文字 \u0401 を形成します。

#define assign(uc1, uc2, val) uc1##uc2 = val
...
assign(\u04, 01, 4);

リスク

C11 規格 (節 5.1.1.2) では、ユニバーサル文字名がトークン連結によって形成されている場合、その動作は未定義になるとしています。

修正方法

トークン連結を介して作成するのではなく、ユニバーサル文字名を直接使用します。

すべて展開する

#define assign(uc1, uc2, val) uc1##uc2 = val

int func(void) {
    int \u0401 = 0;
    assign(\u04, 01, 4); 
    return \u0401;
}

この例では、assign マクロは展開時に 2 つのトークン \u04 および 01 を結合し、ユニバーサル文字名 \u0401 を形成しています。

修正 — ユニバーサル文字名を直接使用

1 つの修正方法として、ユニバーサル文字名 \u0401 を直接使用します。この修正では、トークンが結合されないように assign マクロを再定義しています。

#define assign(ucn, val) ucn = val

int func(void) {
    int \u0401 = 0;
    assign(\u0401, 4); 
    return \u0401;
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: PRE_UCNAME_JOIN_TOKENS
影響度: Low

バージョン履歴

R2018a で導入