Home > ラーニング > セキュアコーディング > C セキュアコーディングスタンダード > 01. プリプロセッサ (PRE)
"?" 二つは3文字表記の始まりを表す。C99 [ISO/IEC 9899:1999] によれば:
次に示す文字の並び[3文字表記(trigraph sequence)という。]がソースファイルの中にある場合、その三つの文字の並びを対応する一文字に置き換える。
??= # ??) ] ??! | ??( [ ??' ^ ??> } ??/ \ ??< { ??- ~
このコード例では、a++ が実行されない。なぜなら、3文字表記 ??/ が \ に置き換えられ、a++ がコメント行と同一行に配置されてしまうからである。
// a の値はなんだろう??/ a++;
以下のコード例は、"?" の間に空白文字をひとつ入れることにより、予期せず3文字表記にならないようにしている。
// a の値はなんだろう? ?/ a++;
このコード例は3文字表記 ??! を含む。これは | に置き換えられる。
size_t i = /* 初期値 */;
if (i > 9000) {
if (puts("Over 9000!??!") == EOF) {
/* エラー処理 */
}
}
C99 に適合したコンパイラを使うと、このコードの出力は Over 9000!| になる。
以下のコード例は文字列連結を用いて二つの "?" を連結している。このようにしなければ、3文字表記の始まりと解釈されてしまう。
size_t i = /* 初期値 */;
/* i への代入 */
if (i > 9000) {
if (puts("Over 9000!?""?!") == EOF) {
/* エラー処理 */
}
}
上記のコードは意図したとおり Over 9000!??! を出力する。
うっかり3文字表記をしてしまうと予期せぬ動作を引き起こすおそれがある。コンパイラによっては、3文字表記がある場合に警告を出すオプションや3文字表記を無効にするオプションを提供している。警告を出すオプションを使用し、コンパイル時に警告が出ないようなコードにせよ。(「MSC00-C. 高い警告レベルで警告を出さずにコンパイルする」を参照)
| レコメンデーション | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
|---|---|---|---|---|---|
| PRE07-C | 低 | 低 | 中 | P2 | L3 |
LDRA tool suite V 7.6.0 はこのレコメンデーションの違反を検出できる。
GCC コンパイラは -Wtrigraphs フラグを使用することでこのレコメンデーションの違反を検出できる。