2024/5/25(土)

cpprefjpを読み進めた。今日からライブラリリファレンスに移る。各ヘッダ名前順ではまとまりがないので、規格で名前が出てくる順に読むことにした。

Common definitions – <cstddef>

  • ptrdiff_t: あんまり意識したことがないが、名前は知っていた。ポインタの差以外に、イテレータの差とかも表すことがあるらしい。
  • size_t: よく使うやつ。
  • nullptr_t: これもよく使うやつ。
  • max_align_t: これは知らなかった。C++11かららしい。alignf(max_align_t)以外の形で使うことがあるのか?そもそも対象となるデータ型を特定せずに最大のアラインメント値を取りたいユースケースが自分には思い浮かばないが。
    調べてみると、1つの例としてはmallocの実装があるらしい。任意の型に対しアラインメントされている必要がある。
  • byte: これは存在を知っていたが、常にあまりよく考えず適当に使っていた。これでcstddefに含まれていることを覚えた。
    ところで、operator<<とかto_integerみたいな小道具が整備されているらしい。ただのunsigned charのエイリアスではない。
  • offsetof: これは低レイヤなプログラムでちょこちょこ使う。
  • NULL: 今はnullptrがある。もう二度と新規に使うことはないだろう。

Common definitions – <cstdlib>

何が入っているかよく知らないので、ちゃんと勉強するきっかけになった。

数値変換

  • atoi, atol, atoll, atof: 中身が安全だと分かっている文字列でしか使ってはいけないと聞いた。atofはfなのにfloat型ではなくdouble型への変換らしい。floatおよびlong doubleへの変換は少なくとも標準にはないようだ。
  • strtol, strtoll, strtoul, strtoull, strtof, strtod, strtold: strtoiはないのか!こいつらはエラーをerrnoで教えてくれるらしい。スレッドセーフなのかが気になったが、errnoという仕組みはスレッドローカルなのでセーフなようだ。

擬似乱数

  • RAND_MAX, srand, rand: お馴染み疑似乱数生成器。C++14でわざわざ非推奨になっていたとは知らなんだ。std::randomをそらで使えるように勉強しておきたい。

メモリ管理

  • aligned_alloc: こんなのあったのか。しかもC++17から!?
  • malloc: いつもの
  • calloc: 思うのだが、mallocとmemsetではいかんのか?調べてみると、システム次第でcallocでは無駄な処理がなくなったりするらしい。
  • realloc: あんまり明確な記述が見つけられないのだが、やはりこいつは行けそうなら同じ場所で領域を拡張したりしようとするらしい。
  • free: いつもの

プログラムの開始と終了

  • EXIT_SUCCESS, EXIT_FAILURE: exitの引数とかに渡すといいらしい。たしかに0とか数字ではマジックナンバーになってしまうから、その点ではこの方が良さそうだ。
  • exit, abort: いつもの
  • quick_exit: これは存在を初めて知った。正常終了なのにわざわざリソース破棄を飛ばす理由はなんだ?と思ったが、マルチスレッドでのロック回避が念頭にあるようだ。納得。
  • atexit, at_quick_exit: 終了時の関数登録。登録と逆順で呼び出されるのは、GoやZigのdefer文を考えれば納得できる。しかし32個とか最低保証数がちゃんとあるのは初耳だった。

環境

  • getenv: 環境変数を取る手段がこれしかないのでよく使っている。いい加減にもうちょっと現代的な環境変数の取得法が整備されてほしい。何度もラッパを書いている。
  • system: いつもの

検索と並び替え

  • bsearch, qsort: この手のアルゴリズム関数がC言語関数でちゃんと用意されているのをあまりしっかり把握していなかった。C言語にテンプレートの概念はないがポインタは存在する。要素のサイズも比較関数もユーザ定義なので、実質どんな型の配列でも二分探索/ソートができる。思ったよりしっかりしてた。

整数に対する算術関数

  • abs, labs, llabs: absはもちろん知っていたがlとかllが付いたバージョンがあるのは認知していなかった。しかしなぜ前に?
  • div_t, div, ldiv_t, ldiv, lldiv_t, lldiv: これは本当に初めて知った。単に/と%を使うより早いケースがあるのだろうか?

マルチバイト文字とワイド文字の変換

codecvtとかいうやつが失敗作として扱われているのに対し、こいつらはどうして普通に生きているんだ?

あくまで実装定義の実行時文字コードである「マルチバイト文字」と「ワイド文字」の間の変換であるこいつらと、Unicodeとかへの真面目な対応を目指しているcodecvtだと話が違うということだろうか。

Categories: