C23 (C言語)

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

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

**標準ライブラリ**

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

**既存の関数**
 printf()とそれに類似する関数に2進数向けの変換指定子の%bを追加。- scanf()とそれに類似する関数に2進数向けの変換指定子の%bを追加。- strtol()とwcstol()とそれらに類似する関数で接頭辞に0bまたは0Bを持つ文字列に対応。- bsearch()、label=bsearch_s()、memchr()、strchr()、strpbrk()、strrchr()、strstr()とそれらのワイド文字対応版のwmemchr()、wcschr()、wcspbrk()、wcsrchr()、wcsstr()でconst修飾オブジェクトが渡された場合にそれを返すようにする。

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

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

**定数**
 C++11#ヌルポインタ|nullptr定数をnullptr_t型に追加。- _BitInt(N)およびunsigned _BitInt(N)型にwbおよびuwb整数リテラル接尾辞を追加。例えば、6uwbはunsigned _BitInt(3)を表し、-6wbは値を表す3つのビットと符号を表す1つのビットを持つsigned _BitInt(4)を表す。- Integer literalに2進数を表す0bおよび0B接頭辞を追加。例えば、0b10101010は16進数を表す整数リテラルの0xAAと等しい。- 数値リテラルの区切り文字として'を追加。例えば、0xFE'DC'BA'98は0xFEDCBA98と等しく、299'792'458は光速|299792458と等しく、1.414'213'562は2の平方根|1.414213562と等しい。- 列挙型|enumの基底型 (underlying type) を指定できる機能を追加。- 基底型が省略されたenumに、intで表現できない値を格納できるようにする。

**キーワード**
 trueおよびfalseキーワードを追加。- alignas、alignof、bool、static_assert、スレッド局所記憶|thread_localキーワードを追加。従来の_Alignas、_Alignof、_Bool、_Static_assert、_Thread_localキーワードはこれらの新しいキーワードの別表記になる。- _BitIntキーワードを追加（#データ型を参照）。- typeofおよびtypeof_unqualキーワードを追加（#データ型を参照）。- nullptrキーワードを追加（#定数を参照）。- constexprキーワードを追加（#その他の機能を参照）。- オプショナルなDecimal floating point演算用の_Decimal32、_Decimal64、_Decimal128キーワードを追加（#その他の機能を参照）。

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

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

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

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

**コンパイラの対応**
以下のコンパイラはC23に実験的に対応しており、これを利用するためのオプションを提供している:- GCC 9- Clang 9.0- label=Pelles C 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つの脚注の修正だけであると明記されている。

**参考文献**
  N3096 (last freely-available working draft before C23); WG14; April 2023. (free download)- N3149 (working draft of C23 standard); WG14; July 2023. (not available to public)- N3219 ( ISO/IEC 9899:2023 DIS Draft); WG14; February 2024. (ISO draft available but not free)- ISO/IEC 9899:2024 (official C23 standard); ISO; 2024. (planning for release in 2024)-  N3220 (first working draft after C23; differs from draft standard N3219 only in one footnote); WG14; February 2024. (free download)

**脚注**

**関連項目**
 C++23、C++20、C++17、C++14、C++11、C++03、C++98 - C++の言語規格- Compatibility of C and C++

**外部リンク**
  C Language WG14 (Working Group 14)
**  WG14 Document Repository
**  WG14 Meetings - agenda and minutes
** WG14 Charters:  C2x Charter,  C23 Charter,  Interpreting the C23 Charter,  C Standard Charter