第10章:C23と将来の展望
この章で学ぶこと
- C23の主要な新機能
- 従来のGCC拡張からの標準化
- 新しい型と構文
- C言語の将来の方向性
typeofとtypeof_unqualの標準化constexprオブジェクト#embedプリプロセッサディレクティブ_BitInt(N)型nullptrとnullptr_t- 属性構文
[[]] auto型推論- 2の補数の義務化
---
10.1 C23概要
ISO/IEC 9899:2024
C23は2024年に正式に承認されました。正式名称はC24ですが、開発中の名称C23が広く使われています。
主な変更点
---
10.2 typeof と typeof_unqual
使用例
int x = 42;
typeof(x) y = x; /* int y */
typeof_unqual(const int) z; /* int z */
/* 複雑な型の簡略化 */
int (*fp)(int, int);
typeof(fp) fp2; /* 同じ型の関数ポインタ */
マクロでの活用
#define swap(a, b) do { \
typeof(a) tmp = (a); \
(a) = (b); \
(b) = tmp; \
} while (0)
---
10.3 constexpr オブジェクト
定義
コンパイル時に値が決定される定数。
constexpr int SIZE = 100;
constexpr double PI = 3.14159265358979;
int arr[SIZE]; /* OK: constexprは配列サイズに使用可能 */
#define との違い
#define OLD_SIZE 100 /* 型なし、スコープなし */
constexpr int SIZE = 100; /* int型、ブロックスコープ可能 */
---
10.4 #embed ディレクティブ
バイナリファイルの埋め込み
static const unsigned char icon[] = {
#embed "icon.png"
};
static const char shader[] = {
#embed "shader.glsl"
, '\0' /* 終端を追加 */
};
従来の方法との比較
/* 従来: 外部ツールでCソースに変換 */
/* xxd -i icon.png > icon.h */
/* C23: 直接埋め込み */
#embed "icon.png"
---
10.5 _BitInt(N) 型
任意幅整数
_BitInt(128) big_num;
unsigned _BitInt(256) huge_num;
/* 最低幅は実装定義、通常 BITINT_MAXWIDTH まで */
_BitInt(BITINT_MAXWIDTH) max_int;
使用例
_BitInt(128) a = 1;
a <<= 100; /* 128ビット左シフト */
---
10.6 nullptr と nullptr_t
NULL の問題
#define NULL ((void *)0) /* または 0 */
void f(int);
void f(int *);
f(NULL); /* どちらが呼ばれる?曖昧 */
nullptr の導入
#include <stddef.h>
nullptr_t np = nullptr;
void *p = nullptr; /* OK */
int i = nullptr; /* エラー */
f(nullptr); /* f(int *) が呼ばれる */
---
10.7 属性構文 [[]]
標準属性
[[noreturn]] void abort_program(void);
[[deprecated("use new_func")]] void old_func(void);
[[maybe_unused]] int debug_var;
[[nodiscard]] int must_use_result(void);
[[fallthrough]]; /* switch内で意図的なフォールスルー */
[[reproducible]] double pure_calc(double x);
[[unsequenced]] int no_side_effects(int x);
GCC属性との共存
/* C23 */
[[nodiscard]] int important(void);
/* GCC/Clang(引き続き使用可能) */
__attribute__((warn_unused_result)) int important(void);
---
10.8 その他の変更
auto 型推論
auto x = 42; /* int */
auto p = &x; /* int * */
auto f = func; /* 関数ポインタ */
ラベル前の宣言
switch (x) {
int local; /* C23: OK */
case 1:
local = 1;
break;
}
2の補数の義務化
符号付き整数は2の補数表現が必須に。1の補数、符号絶対値は廃止。
true/false のキーワード化
/* C11以前: <stdbool.h> のマクロ */
/* C23: 言語キーワード */
bool b = true; /* <stdbool.h> なしで使用可能 */
---
10.9 将来の展望
検討中の機能
C++との関係
C23は多くの機能をC++から取り入れました:
constexprnullptrauto- 属性構文
組み込み・システムプログラミング
C言語は引き続き以下の分野で重要:
- OSカーネル
- 組み込みシステム
- ドライバ
- セキュリティクリティカルなソフトウェア
typeof/typeof_unqualconstexpr#embed_BitInt(N)nullptr[[]]属性構文auto型推論- コンパイラサポートの確認
- 段階的な導入
- 後方互換性の維持
---
10.10 この章のまとめ
C23の主要機能
移行のポイント
---
確認問題
問題1
constexpr と const の違いは?
解答
constexpr: コンパイル時に値が決定。配列サイズなどに使用可能。const: 実行時に初期化可能。修飾された変数は変更不可だが、配列サイズには使用不可(VLAになる)。
問題2
nullptr と NULL の違いは?
解答
nullptr: 型安全なヌルポインタ定数。整数への暗黙変換なし。NULL:(void *)0または0のマクロ。整数との区別が曖昧。
問題3
#embed の利点は?
解答
バイナリファイルを直接Cソースに埋め込める。外部ツール(xxd等)が不要になり、ビルドプロセスが簡略化される。
---
おわりに
この教材では、C言語の規格レベルでの理解を目指しました。
学んだ内容:
- 規格文書の読み方
- 型システムの厳密な定義
- オブジェクトと値の表現
- 未定義動作の回避
- 処理系定義動作と移植性
- 厳密なエイリアシング規則
- メモリモデル
- 標準ライブラリの仕様
- コンパイラ拡張
- C23の新機能
規格に基づいた正しい理解は、移植可能で信頼性の高いコードを書くための基盤です。
C言語は50年以上の歴史を持ちながら、今も進化を続けています。規格を読み、理解し、正しく使いこなすことが、真のCプログラマーへの道です。