Modern C C23エディション
(gustedt.wordpress.com)- 新しいC標準に合わせたModern C改訂版が無料ダウンロードとして公開され、C言語の学習・参照資料をC23基準であらためて見直せる
- 改訂の中心はC23対応であり、ISOの出版手続きと時期に合わせて新標準への移行を支援することに焦点がある
- 主要コンパイラの新しいリリースはC23機能の大半をすでに実装しており、書籍の変更点が実験的な紹介にとどまらず実際の利用環境と結び付いている
_BitInt(N),nullptr,auto,typeof,constexprなど、言語・ライブラリの変化が幅広く反映され、従来のCコードの書き方にも影響を与える- 既存プラットフォームですぐ試せるように移行用付録と暫定includeヘッダが追加されたが、ManningのMEAPはまだ進行中である
無料公開資料と標準文書
- Modern C C23エディションは無料でダウンロードできる
- 書籍専用ページで関連資料もあわせて探せる
- 専用ページ: https://gustedt.gitlabpages.inria.fr/modern-c/
- 書籍に付属するコード例のダウンロードリンクもこのページにある
- 改訂版ではさまざまな説明が見直されているが、核心的な目的は新しいC標準であるC23を反映することにある
- 公開アクセス可能な文書の中では、新標準の内容にもっとも近い資料はN3220 PDFである
- 主要コンパイラの新しいリリースは、C23がもたらす新機能の大半をすでに実装している
C23の言語変化と移行支援
- 整数関連の変化が大きな比重を占める
- 新しいビット精度型**
_BitInt(N)**を追加 - オーバーフローチェック演算とビット操作のための新しいCライブラリヘッダを追加
- 現代アーキテクチャにおける128ビット型の可能性を反映
- enum型の実質的な改善も含む
- 新しいビット精度型**
- C23のその他の新しい概念も含まれる
- **
nullptr**定数とその基盤型 - attributesによる構文注釈
autoとtypeofを含む型ジェネリックプログラミングの道具- 可変長配列にも適用される
{}によるデフォルト初期化 - あらゆる型の名前付き定数のための
constexpr
- **
- 新しい資料では、複合式、ラムダ、「国際化」、プログラム失敗に対する包括的なアプローチまで扱う
- 既存プラットフォームでC23をすぐ始められるように付録と暫定includeヘッダが追加された
- Manningの新エディションMEAPはまだ公開中である
- MEAP: https://www.manning.com/books/modern-c-third-edition
- Manning版C23エディションの最終出版時期はまだ分かっていない
1件のコメント
Hacker News の意見
私のマシンの格納順序であるリトルエンディアンとは異なり、上位桁の表現が先に来る方式はビッグエンディアンと呼ばれるが、現代のプロセッサでどちらも一般的に使われていると言うには、s390x 以外はほとんど残っていないので、少し誇張に感じる
そろそろ、みんな大好きなニッチ/廃れたビッグエンディアン・アーキテクチャのコメントが付きそう
他の上位コメントにもあるように、「現代的」という言葉は必ずしも人気がある、あるいは広く使われているという意味ではない
AIX と IBM i は IBM メインフレームほど活発ではないだろうが、AIX は Solaris や HP/UX よりもまだ生きていると言えるし、かつて数多くあった商用 Unix と比べればなおさらだ。IBM i もかろうじて踏みとどまっているが、HP MPE のようにベンダーサポートが公式に終了した競合のレガシー・ミッドレンジプラットフォームよりは、はるかに生きている
C の最も重要な側面は移植性だ。小さなマイクロコントローラからほぼすべてのコンピューティングプラットフォームまで対応できることが核心だが、新しい C バージョンがそこまで採用されるかは疑問だ
最先端を使いたいなら、C より C++2x や Rust を選ぶと思う。何か見落としているのだろうか? このいわゆるモダン C がもたらす利点が何なのか気になる
最先端なら Zig を勧める。現代の C++ や Rust より言語の複雑さがずっと低い。C23 の目立たない良い副作用として、
... = {}や{0}のような構文を C++ により合わせたことで、C ライブラリのメンテナが C コードを C++ コンパイラでビルドしようとする人たちをサポートする面倒が減る、ということがある0bはマイクロコントローラの世界で広く使われているマイクロコントローラのツールチェーンは概して GCC の上に作られているので、機能をタダで得られる。常に遅れがちなプロプライエタリな C コンパイラもあるが、20 年前ほど重要ではない
組み込みや非常に広いアーキテクチャ集合を対象にしていないなら、今日から C23 を使えない理由もない
thread_local指定子はすでにいくつかのマイクロコントローラプラットフォームで使われているが、C11 以前では完全に違法だった。それでもスレッド環境でのメモリ管理を大きく単純化するそのためにわざわざ C++ の世界へ入る理由があるだろうか?
個人的に
guard、defer、auto、constexpr、nullptrのようなものは C をずっと複雑にする。単純さが必要だから C を選ぶのに、複雑さが欲しいなら、たいていは望まなくても C++ を選ぶだろうし、むしろ Go や、サーバなら Elixir を選ぶ_BitInt(N)も不格好で、幸い今ではboolになった_Boolを思い出す。constexprとnullptrは C++ 臭が強すぎる。それでも Modern C は素晴らしい本で、使い続けるつもりの C99 用として大いに役立ってきたNULLの何が問題なのかという疑問は、ISO 標準化の数少ない利点のおかげで、関連文書を読めば答えが出る: https://wg21.link/p2312要約すると、
NULL引数を型ジェネリックマクロに渡すと驚くような結果が生じる可能性があり、(1 ? 0 : NULL)や(1 ? 1 : NULL)のような条件式の扱いがNULLの定義方法によって変わる。また、ポインタを期待する可変引数関数にNULLを渡すと深刻な結果になり得る。最近の多くのアーキテクチャではintとvoid*のサイズが違うため、NULLが単なる0だと、誤ったサイズの引数が関数に渡される家を建てるのと似ている。ハンマーとドライバーは非常に単純で、クレーンは極めて複雑だが、家づくりを単純にするのはクレーンだ。ハンマーとドライバーだけで家を建てようとすれば、途方もなく複雑な手順を考案しなければならない
プログラミング言語も同じだ。C++ でジェネリックコンテナを作るのは些細なことだが、C では非常に難しい。
void *と手動キャストである程度まねることはできても、面倒でエラーを起こしやすく、コードはより複雑になるstd::sortとqsortも同じだ。テンプレートと関数オブジェクトの力で、実装はより単純で速くなる。void *を渡して実行時に逆参照する必要がなく、比較を関数定義そのものに入れられる。間接呼び出しもスタック渡しもなく、比較関数のインライン化まで可能だ。言語の複雑さは実装の複雑さを意味しないautoは型ジェネリックマクロを扱うときには主に有用だが、通常のコードでは使わないほうがよい。しばらく C++ の世界で流行した almost always auto のような狂気は避けたい残念ながらコンパイラごとに少し違いがある。記憶では、Clang は C++ 風の
autoを実装し、GCC は C 風のautoを実装していて、autoポインタで微妙な違いがあった。その違いが今は修正されたのかは分からない_BitInt(N)は普通は直接使わず、必要な幅でtypedefして使う。たとえばtypedef _BitInt(2) u2;のように使う。_Bのような不格好な構文は、アンダースコアに続く大文字の組み合わせが C 標準で予約されているため、言語に小さな機能を追加するときに既存コードと衝突しないようにするため必要だ。_Boolという名前も同じ理由だ。私の知る限り、deferは実際には C23 には入らなかった以前の定義では、
NULLがポインタなのか整数なのかさえ指定していなかった。そのため、Posix の((void*)0)要件に従わないプラットフォームでは、ポインタ型でもサイズでもない足元の落とし穴だったconstexprとnullptrが C++ っぽいのは、おそらく C++ から逆輸入されたため。それでもNULLは引き続き使えるが、見た目にはnullptrとして再定義されたようだexeclp("echo", "echo", "Hello, world!", NULL);このコードにはそのバグがない:
execlp("echo", "echo", "Hello, world!", nullptr);これでもよい:
execlp("echo", "echo", "Hello, world!", (char *)NULL);良い C の本リストがあるか尋ねようとして、自分で答えを見つけた。ここでは Modern C を中級に分類している
https://stackoverflow.com/questions/562303/the-definitive-c-...
K&R の現代的な C の伴読書としては、Ben Klemens の 21st Century C と King の C Programming: A Modern Approach のほうが、より取り組みやすい代替だと思う
個人的には Modern C より Effective C のほうが好きだ。Modern C は非常に厳密で、専門家には必要かもしれない言語注釈付き仕様書を読んでいるような感じで、私のように軽く C を使う人間には読んでいて退屈だ
Metaware の High C 拡張の一部はかなり気に入っている
https://news.ycombinator.com/item?id=41647843
https://news.ycombinator.com/item?id=38938402
この1年以上、個人プロジェクトの言語インタプリタにモダン C++ を使っているが、C++ の精神的負担とツールの問題のため、C に切り替えようかと考え続けている。Visual Studio の IntelliSense は C++20 モジュールを使うと今でもほとんど動作せず、言語の失敗のせいであまりに多くのものがインターフェースへ押し出され、コンパイル時間もひどいものになる
その一方で、クラス、メンバー関数、ジェネリックプログラミング、名前空間にあまりにも慣れてしまっていて、もう捕まってしまった気もする
その用途なら C# を検討してみた? Visual Studio は C# との相性のほうがずっと良い
macOS Preview でサイドバーの 目次リンク をクリックしても正しく動作しない
保守しているライブラリで、C コンパイラがすべて C99 をサポートしていると信じられるようになったのは、ほんの数年前のことだ: https://github.com/eyalroz/printf
ところが数年たつと案の定、どこかの古代の組み込みツールチェーンのために C89 互換性を求める issue が開かれた。だから C23 は良いのだが、20年後くらいにまた話そうという感じだ
実務上、C がなぜ事実上 C99 で止まっているのか を説明する記事を誰かリンクしてくれないだろうか? 話題にする価値のあるプロジェクトで、C11 以降の機能を活用しているものはほとんどない
何十年もの間 C は事実上凍結されていたため、ユーザー層も、C が今のままであることを好み、古代のガラクタのようなコンパイラのサポートをいとわない人たちへと自然選択されたように思える。忍耐を失った人や21世紀の言語を望んだ人たちは、C++/Rust/Zig などへ去っていった
2010年ごろには MSVC は依然として非常に重要だったが、最近はほとんどの開発者が Linux に移ったように見える視点からすると奇妙に聞こえる。一方で、C11 機能をどうしても必要とするプロジェクトも多くない。C11 は C99 から VLA を取り上げもしたが、それほど惜しい損失ではなかった。C23 は、C99 以降で多くの C コードベースが実際にアップグレードする価値のある最初のバージョンかもしれない