C23 (C言語)

C23（ISO/IEC 9899:2024）とは、C言語の現在のオープン標準であり、（ISO/IEC 9899:2018）の後継規格である。2016年にC2xとして非公式に策定が開始され、2024年10月31日に発行された。発行された規格に最も近い自由に入手できる草案はN3220である（#利用可能な文書を参照）。C2x草案の最初のWG14会議は2019年10月に開催され、新型コロナウイルス感染症の世界的流行によって2020年は仮想リモート会議として開催され、その後、2024年まで様々な遠隔会議が継続的に開催された。

C23では、の値がからに変更される。一般名の「C17」や「C23」はISO規格識別子の年（9899:2018と9899:2024）ではなく、規格発行前に固定されるこれらの値を反映している。

 機能 

C23の最新の作業草案に統合された変更点は以下の通りである。

 標準ライブラリ 

 新規関数 

 <>に関数を追加。機密データを消去する目的で、最適化に関係なく常にメモリ書き込み (store) を実行する必要がある場面で使用される。
 に()関数を追加。文字列を効率的に連結する。POSIXとSVIDのC拡張と同様である。
 に()および関数を追加。文字列の複製を割り当てる。POSIXとSVIDのC拡張と同様である。
 ポインタのバイトアライメントを決定するために<>に関数を追加。
 新たなヘッダの<stdbit.h>を追加し、多くの整数型でビット関連の操作をするための関数、マクロ、データ型を定義。全てstdc_で始まるので古いコードやサードパーティのライブラリとの競合を最小限に抑えることができる。
 以下の*は特定の整数型向けの関数ではこれを、、、、のいずれかに置き換え、ジェネリック関数ではこれを除去して読む。
 ビットで表現した場合の1または0の個数を数えるおよび関数を追加。
 ビットで表現した場合の先頭の1または0の個数を数えるおよび関数を追加。
 ビットで表現した場合の末尾の1または0の個数を数えるおよび関数を追加。
 ビットで表現した場合に最上位ビットから数えて最初に1または0が現れる位置を探すおよび関数を追加。
 ビットで表現した場合に最下位ビットから数えて最初に1または0が現れる位置を探すおよび関数を追加。
 値が正しく2の冪乗であるかを確認する（単一のビットだけが1の場合にを返す）関数を追加。
 与えられた値より大きくない最大の2の累乗を計算する関数を追加。
 与えられた値より小さくない最小の2の累乗を計算する関数を追加。
 与えられた値を表すのに必要なビット数を調べる関数を追加。
 <time.h>にglibcとmuslにあるような時間を表す構造体をに変換できる関数を追加する。
 <>にIEEE 754-2019の推奨に基づく単位で動作する三角関数やexp10などの関数を追加。

 既存の関数 

 とそれに類似する関数に2進数向けの変換指定子のを追加。
 とそれに類似する関数に2進数向けの変換指定子のを追加。
 ととそれらに類似する関数で接頭辞にまたはを持つ文字列に対応。
 ()、()、()、()、()、()、()とそれらのワイド文字対応版の()、()、()、()、()でconst修飾オブジェクトが渡された場合にそれを返すようにする。

 プリプロセッサ 

 およびディレクティブを追加。これらは基本的にとと同じである。これらはどちらもとGCC 12に追加された。
 バイナリリソースを埋め込むためのディレクティブとプリプロセッサディレクティブによってリソースの存在を確認できるようにするを追加。
 診断用のディレクティブを追加。
 ヘッダの存在をプリプロセッサディレクティブで確認できるようにするを追加。
 属性の存在をプリプロセッサディレクティブで確認できるようにするを追加（新たな属性機能については#C++との互換性を参照）。
 マクロを追加。これはマクロのパラメータとして受け取った可変長引数が空でない場合に置換するトークンを指定する。

 データ型 

 ヌルポインタ型のを追加。
 正確なビット単位の数値を表すおよび型を追加。最大ビット幅を表すマクロを追加。
 オーバーフローを検査する整数演算用の、、マクロを追加。
 可変変更型（スタック上に割り当てられるである可変長配列は除く）が必須機能になる。
 配列でのの使用に対する対応の向上。
 (...)演算子が標準化。
 キーワードの意味は、型推論をもたらすように変更されたが、一方で型と同時に指定された場合、従来の古い意味であるとなる機能も引き続き保持している。C++とは異なり、C23では変数宣言でのみ型推論が許可されている（関数のパラメータや戻り値の型に対しては認められない）。
 構造体、共用体、列挙型の互換性ルールが変更され、同じタグを持つ互換性のある型の再宣言が可能となった。
 固定長整数型の幅がを超える可能性があるようになった（N2888）。

 定数 

 定数を型に追加。
 および型におよび整数リテラル接尾辞を追加。例えば、はを表し、は値を表す3つのビットと符号を表す1つのビットを持つを表す。
 に2進数を表すおよび接頭辞を追加。例えば、は16進数を表す整数リテラルのと等しい。
 数値リテラルの区切り文字としてを追加。例えば、はと等しく、はと等しく、はと等しい。
 の基底型 (underlying type) を指定できる機能を追加。
 基底型が省略されたに、で表現できない値を格納できるようにする。

 キーワード 

 およびキーワードを追加。
 、、、、キーワードを追加。従来の、、、、キーワードはこれらの新しいキーワードの別表記になる。
 キーワードを追加（#データ型を参照）。
 およびキーワードを追加（#データ型を参照）。
 キーワードを追加（#定数を参照）。
 キーワードを追加（#その他の機能を参照）。
 オプショナルな演算用の、、キーワードを追加（#その他の機能を参照）。

 構文 

 ラベルをの前と複合文の末尾に配置できるようになる。
 関数定義でパラメータ名を省略可能に。
 によるゼロ値初期化（可変長配列の初期化を含む）。
 可変長引数関数は省略記号（）の前に名前付きパラメータを必要としなくなり、マクロは2番目の引数を必要としなくなり、最初の引数の後に引数があっても評価しないようになった。
 C++11形式の二重角括弧（）を使用する属性構文を追加。C23ではC++にはない以下の独自の属性が追加される:
 属性は引数が同じならば常に同じ結果を返し、他のデータに依存関係を持たない関数型に対して付与する。
 属性は属性に似ているが関数の呼び出し順序も重要である場合に付与する。
 C++17との互換性のためにに単一引数を追加。
 プロトタイプ宣言で引数がない関数（例えば）は、引数を取らない関数であるとして扱われる（#廃止された機能を参照）。

 C++との互換性 

 宣言の前のラベル、関数定義でのパラメータ名の省略の許容、によるゼロ値初期化、可変長引数関数での名前付きパラメータのオプショナル化、C++11形式の属性、（#構文を参照）などの様々な構文の変更によりC++との互換性が向上した。複合文の末尾でのラベルについてはC23の互換性のためにで許可されるように変更された。
 C++形式の属性を追加（#構文を参照）。C++11との互換性のために、、、、属性が追加され、C11で導入された、、ヘッダは非推奨となった。との互換性のために重複する属性は許可されれている。全ての標準属性は二重アンダースコアで囲むことができる（例えば、はと同じ）。
 C++17との互換性のためにUTF-8で符号化されたを表すための接頭辞を追加。
 との互換性のためにおよびディレクティブを追加（#プリプロセッサを参照）。

 その他の機能 

 浮動小数点数演算のためにIEEE 754の現行版であるISO/IEC 60559:2020に対応し、拡張された二進浮動小数点数演算とオプショナルの十進浮動小数点数演算に対応する。
 C++のそれとは異なり、指定子は定数宣言でのみ使用でき、関数は認められていない。
 UTF-8で符号化されたデータを格納するための型が追加され、文字（列）リテラルの型がに変更される。また、型のマルチバイト文字列と型のUTF-8文字列を変換するためのとが追加された。
 明示的に指定されていない限り、全ての文字列（リテラル）がUTF-16で符号化されること、全ての文字列（リテラル）がUTF-32で符号化されることが保証されなければならないことが明文化された。
 複合リテラル定義で記憶域クラス指定子を使用することを許容する。

 廃止された機能 

いくつかの古く廃止された機能がC23の作業草案では削除または非推奨となった:

 トライグラフは削除された。
 K&R形式の引数の情報のない関数定義は削除された。
 2の補数以外の符号付き整数の表現は削除され、符号付き整数は2の補数形式で表現することが必須となった。
 のマクロは廃止予定の非推奨機能となった。

 コンパイラの対応 

以下のコンパイラはC23に実験的に対応しており、これを利用するためのオプションを提供している:

 GCC 9
 Clang 9.0
 11.00

 利用可能な文書 

C17などの他のC言語の標準規格と同様に、C23のISOの公式規格書は自由に入手することはできない。

C23の仕様が確定する前の最後の作業草案は2023年4月1日付のN3096である。この草案の後の数カ月間、2023年7日9日付の作業草案N3149と2024年2月22日付の公式標準草案N3219が作成されるまでに数百の変更が行われた。これら以降の草案は非公開である。

標準草案N3219が発表されたのと同日、新たな作業草案N3220が公開された。この草案は公式には将来のC言語の標準である「C2Y」の草案であると説明されているが、付随する「編集者レポート」では、N3219との違いは付録Kの1つの脚注の修正だけであると明記されている。