Linuxのデスクトップとサーバーについて扱います。11日目の前日はegtra氏の「配列でないオブジェクトに対するポインタ演算」でした。@MNukazawaといいます。今、ベクターグラフィック・エディタをC言語で書いています。Vecterion(べくてりおん)という名前です。VecterionはGtk3/C言語で書いています。現在進行形ですが、今日はVecterion開発の知見というか、Vecterionで使っているちょっと大きめのイディオムを、いくつか紹介したいと思います。多人数で開発しなきゃ作れないアプリケーションを大規模として、コマンドラインスクリプトよりは高度なことをしているけれど、コード量としては一人で収まる。小規模と大規模の間くらい、程度の意味です。小規模は、(語弊があるが)catやechoのような、ワンパスのコマンドラインスクリプト程度の機能。LibreOfficeのようなGUIエディタや、Linuxカーネルなど。なんというか、中規模コードの良い例を見つけることができなかったので書きました。どなたかオススメのプロジェクトをご存知の方は教えてください。開発中プロジェクトでまだ悩み中(本当は良くない)なので、まとまりきらない内容になっていますが、あなたが中規模プロジェクトを書く際に、一部でも参考になれば幸いです。ソース構成struct型の定義と一緒に、メンバ関数・構造体を操作するUtility関数を同じヘッダに置いている。CヘッダとCソースは原則的に一対一対応させている。これらのソース構成は、ビルド速度的には最善ではないが、関数の置き場所がわかりやすく、プロジェクト全体の読みやすさに繋がる。入れ子に宣言定義(?)できないので、その時は諦めて#defineを使う。Gtk的な関数名の付け方を、そのままソースの名前にしている。効く名前を付けるべき。今はGtk3ライクな名前を付けている。vim上で一意性のある名前にするかは悩ましい(悩んでる)ctags対応には一意な名前を付ける。変に同名(static関数とか?)を付けなければ大丈夫。開発中のプロジェクトは、実装により適切な名前が別にあることがわかったりするので、関数ローカルの一時変数名まで、置き換えを意識して付けるようにしている。*/*.[hc]が効くように名前を付ける。"Doc"を"Document"に直すときに、「ほぼ一括置換」くらいの手間で置き換えられる状態を目指している。g_strdup_printfは、それが無い環境では互換関数を書いたりしている。未定義動作を避ける最近は浸透してきた?未定義動作の存在の認知度ってどのくらいなのだろう。ヘッダはシステム、自分ソースの順ヘッダを書き間違えた時にとんでもないエラーメッセージが出ることがあるので、ヘッダはシステムヘッダを上に書く。言いつつ、.h:.c一対一対応のコードはCソースの一番上に対応ヘッダファイルを書いているが。icon_id)のほうが良いかと。内部的にはint的なモノなのであくまで読みやすくするだけの糖衣。コンパイラチェックが得られるとは期待しない。classメンバなんて、C関数self引数の糖衣構文に過ぎない的思想。最初はthisと名づけていたら、googletest側でC++予約語と衝突して、selfにリネームしなければならなくなった。VimのデフォルトとLinuxでインデントルール衝突しているがまあそれはそれ。switch文は縦横サイズを食うので、サンプルコードは略す。不満はあるが、Info型をKind,Id,Indexのいずれかで引く方式を使っている。データ構造の生成というか確保というかmalloc,freeで生成・削除し、ポインタで保持する。構造体の中身を見せたくなければ、Cのimplイディオムのように、ヘッダに宣言のみ書く方法で定義を隠す。可変長配列は、ポインタ配列をポインタポインタで確保して使うことで実現している。Cを使っているので、可変長配列が使いたければmalloc,freeと仲良くするしかない(mallocの速度については必要になるまでは忘れる)。*_get_parray_num()トリックで個数を取るとイテレートがやりやすい。定型文になりつつある。*is_error)"引数が不正な場合、Vecterionはabort()するが、PhotonVectorはエラーを返す方針。__VA_ARGS__)¬===...という感じです。本当はもっといろいろありますし、どうしてこれが良さそうか、という理由も、いずれ書こうと思っています。VimでCアプリケーションを開発する話を書く予定です。そちらもよろしくお願いします。12日目の記事でした。