syghの新フラグメント置き場

プログラミングTipsやコード断片の保管場所です。お絵描きもときどき載せます。

C/C++がクソ言語である最大の理由

C/C++には公式の言語リファレンスが存在しません。言語仕様や標準ライブラリ仕様を正確かつ明快に記述した無料の公式オンラインドキュメントが存在しないんです。
正直、これは致命的とも言えるレベルの欠陥だと思っています。これがクソ言語たる最大の理由です。それ以外の問題は正直たいしたことではありません。

Q. Cで分からないことがあるんだけど、これは何を調べればいいのかな?

A. ISO/IEC 9899 を読め。

Q. C++で分からないことがあるんだけど、これは何を調べればいいのかな?

A. ISO/IEC 14882 を読め。

JavaC#のようなまともな言語とその標準ライブラリには、公式のオンラインリファレンスマニュアルが存在しています。日本語版は翻訳の品質が低くて嘘が書かれていることも多々ありますが、少なくとも英語版を読めば正しい最新情報が誰でも得られるわけです。翻って、C/C++にはそんなものありません。一応 cppreference.com というWikiサイトはあるんですが、実はWikipediaと同様、匿名で誰でも内容を書き換えることができてしまいます。当然、嘘や不正確な情報が書かれている危険性もあるわけです*1。ユーザー数の多い英語版は大抵間違いに気づいた人が修正をかけてくれていますが、ユーザー数の少ない日本語版は放置されていることが多いです。正確な情報を得るには、規格書を読むしかありません。しかし無料で公開されているのはドラフト版のPDFのみだったりします*2。こんな中途半端なシロモノを誰かに勧めることができますか?

他にも日本語ではcpprefjpというサイトもありますが、ここもやはり間違いが含まれていたり*3、言語仕様全体を網羅していなかったりと、包括的に利用できるレベルには到達していません。

過去の記事で以前も述べたことがありますが、ハッキリ言ってC/C++というのは21世紀の新しいアプリケーション開発で採用するべき言語ではありません。今よりずっと貧弱だった、いにしえのコンピュータにおける制約に由来する未定義動作や未規定動作/処理系依存動作があまりに多すぎる*4*5。つまりプログラマが事前に注意すべき事柄があまりに多すぎて、おいそれと触ることができなくなっているからです。言語仕様を完全に理解していないと将来に渡って禍根を残す地雷を埋設してしまう羽目になるような言語、自分の脚を撃ちぬくことも簡単にできてしまうような危険な言語、そして何が危険であるかということを正確に知るために本来もっとも必要とされているはずの公式取扱説明書が無料で手に入らないケチな言語を、誰かに勧められるわけがないでしょう。ましてやプログラミング初心者であればなおさらです。もし初心者が最初に触れる言語がC/C++であったら、それは不幸でしかありません。プログラミングが嫌いになる可能性が非常に高くなるだけです*6。教える側もつらい。C/C++は、生のハードウェアやオペレーティングシステムに近い層にアクセスし、コンピュータの動作を理解するには最適な言語であり、今後もバックエンドの記述向けには一定のシェアを維持していくでしょうが、そうでないケースでC/C++を採用するというのは、あなたの時間をドブに捨てているのと同じです。
さあ、アプリケーションプログラマは今すぐC/C++をドブに捨てて、人間にやさしい真の高級言語を選択し、あなただけの優雅で知的な時間を確保しましょう。

*1:一番恐ろしいのは、「ほとんどの情報は正しくて、ごく一部だけ間違っている」というケースです。「木を隠すには森の中」とはよくいったもので、多数の真実の中にごくわずかな嘘を混ぜると大多数の人間は騙されて信じてしまいます。たとえそれが明らかな間違いであったとしても。

*2:最近は言語仕様改訂の頻度が上がっているのですが、有用な機能以上に自己満足的で余計なオナニー機能が多数追加される事態になっています。C++20でchar8_t型を追加した際、既存のUTF-8リテラルの型を変更してしまうなど、破壊的な仕様変更すら入るようになりました。JavaC#も以前より仕様改訂の頻度が上がっているものの、かなり慎重に後方互換性に配慮したアップデートがされていますが、C++はダメですね。仕事が雑すぎる。C++11で息巻いて追加したライブラリも、C++17以降で非推奨となったものが多々あります。標準化委員会は現実を知らない頭でっかちな連中ばかりで、そのうえ思慮が浅く、実際のアプリケーションなどひとつも開発したことがないんでしょう。

*3:例えばC++14におけるconstexprの制限緩和について、「既存コードの互換性は壊れない」と吹聴していますが、明らかに大嘘です。新しい規格で非合法(コンパイルエラー)になるような仕様変更はまだ可愛いほうで、旧規格・新規格の双方で合法かつ挙動が異なる仕様変更は、最悪の形で既存コードの互換性を破壊します。c++ - What changes introduced in C++14 can potentially break a program written in C++11? - Stack Overflow

*4:コンパイラが出す警告やエラーに関しても、詳細は処理系に委ねられており、処理系Aでは警告/エラーが出ないのに処理系Bでは警告/エラーが出る、といったことは日常茶飯事です。異なるコンパイラを使うC/C++プログラマは、互いに会話が通じません。移植性のない不適切なコードを書いてしまっても警告が出ないことも多く、プログラマに重い負担がのしかかります。一方JavaC#は、コンパイラの実装がほぼ公式一択なので、こういった処理系間の差異に頭を悩ませる必要がないという点も使いやすさに拍車をかけています。ちなみにJavaには仕様に合致しているかどうかのコンフォーマンステストもあり、テストを通過しなければJavaを名乗ることはできません。Androidは互換性のない非公式のJava実装 (Dalvik VM) を持ち込み混乱をもたらしましたが、このような愚行は非難されて当然です。

*5:C/C++がどのくらい雑に設計されたゆるふわクソ言語であるかは、次の資料を軽く読むだけで分かります。標準規格と処理系 - cpprefjp C++日本語リファレンス

*6:自分は学生の頃、最初に購入させられたテキストが『プログラミング言語C(通称K&RのC)』でした。この本の難解さには定評があり、案の定Cのポインタで挫折しかけたのですが、『C言語ポインタ完全制覇』という良書に出会って克服し、また『Delphiオブジェクト指向プログラミング』という良書に出会って(C++ではなく)Object Pascalで最初にオブジェクト指向を学習したため、幸いにもプログラミングを武器にして生き残ることができました。