最終更新日時: 2026年06月25日 15時15分02秒 (JST)
Akira Takahashi が更新

履歴 編集

# プリプロセッサ仕様での「未定義動作」を不適格 (診断不要) に変更 [P2843R3](C++26)

このページはC++26に採用される見込みの言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

## 概要

C++26では、プリプロセッサおよびレキサーの仕様において「未定義動作 (undefined behavior)」と規定されていたすべてのケースを「不適格、診断不要 (ill-formed, no diagnostic required; IFNDR)」に変更する。

さらに、各ケースを個別に分析し、多くのケースで診断 (コンパイルエラー) を要求するか、適格なプログラムとして受理するよう仕様を改善する。

未定義動作は本来、適格なプログラムの実行時の動作に対する概念である。プリプロセッサはソースコードをコンパイル前に変換する処理であり、実行時の動作ではないため、「未定義動作」という用語は不適切であった。不適格 (診断不要) への変更は、コンパイラの振る舞いを実質的に変えるものではないが、仕様の正確性を向上させる。

## 変更の対象

以下のプリプロセッサ機能において、従来「未定義動作」とされていた規定が変更される。

対象 | C++23までの規定 | C++26での変更
--- | --- | ---
`defined`演算子のマクロ展開による生成 | 未定義動作 | 不適格 (診断不要)
`#include`ディレクティブのマクロ展開後の不正な形式 | 未定義動作 | 不適格 (診断不要)
マクロ引数内のプリプロセッシングディレクティブ | 未定義動作 | 不適格 (診断不要)
`#`演算子の結果が不正な文字列リテラル | 未定義動作 | 不適格 (診断不要)
`##`演算子の結果が不正なプリプロセッシングトークン | 未定義動作 | 不適格 (診断不要)
`#line`ディレクティブの範囲外の値 (0や2147483647超) | 未定義動作 | 条件付きサポート
定義済みマクロ名の`#define`/`#undef` | 未定義動作 | 不適格 (診断不要)
キーワードと同名のマクロの`#define` | 未定義動作 | 不適格

「不適格 (診断不要)」は、そのプログラムが規格に適合しないことを意味するが、コンパイラが診断メッセージ (エラーや警告) を出す義務はない。「不適格」は、コンパイラが診断メッセージを出す義務がある。

## 参照

- P2843R3 Preprocessing is never undefined
- P4136R2 `#line` is not in line with existing implementation
  - 本提案で不適格に変更した`#line`の範囲外の値を、条件付きサポートに緩和した