C++ Builder XE4
デフォルト引数
自分が使うC++ Builderなどで「デフォルト引数」「デフォルトパラメータ」という機能があります (以下、デフォルト引数と呼びます)。
関数の引数の初期値を関数宣言部で指定しておくことで、関数コール部分で指定する必要がない機能と認識しています。
デフォルト引数を使った実装を読むなかで、自分が「読むのに手間がかかる」と感じた経験から、デフォルト引数を使わないようにしています。
例
例として、様々なセンサーを初期化する処理を上げてみます。
様々なセンサーに対して、通信速度(bps)をそれぞれ自由に設定できる場合とします。
そのコードに対して***「それぞれのセンサーの通信速度は何か?」***を確認するソースリーディングを考えてみます。
デフォルト引数を使わない場合
void initDevices()
{
// 初期化(通信速度bps)
initDHT22(1200);
initRHT03(2400);
initSi7021(1200);
initTMP104(2400);
...
}
上記のコードの場合、initDevices()を見た時点で「それぞれのセンサーの通信速度は何か?」を確認できます。
2-3秒で全てのセンサーの設定を確認できるでしょう。
デフォルト引数を(一部)使った場合
void initDevices()
{
// 初期化(通信速度bps)
initDHT22();
initRHT03();
initSi7021(1200);
initTMP104(2400);
...
}
上記の場合、「DHT22とRHT03のデフォルト引数の値は何か?」という疑問を持ちます。
それらを知るためにはヘッダーの宣言をgrepで検索するか、IDEの関数引数ポップアップ機能などを使います。
ヘッダーを確認する場合でも、ポップアップで確認する場合でも、それぞれ「一つの関数ごと」にしか確認できません。
10個のセンサーを初期化する処理をinitDevices()で行う場合、一つの確認に2秒かかるとする(*1)と最大20秒の時間を通信速度を見るために使うことになります。
この作業を自分は「ソースリーディングを中断する」と考えています。
*1) F1などのキー入力、ポップアップの表示、ポップアップの消失時間の合計
短期記憶の容量 (mental juggling, mental baggage)
人の短期記憶の容量は7±2と言われることがあります。
10個の通信速度デフォルト引数の値を短期記憶に格納するのは7+2を超えます。また、短期記憶の項目が増えることは、Code Completeの「mental juggling」(やThe Art of Redable codeの「mental baggage」)になります。
ソースは書くよりも読まれる方が多い
@ プログラマが知るべき97のこと by Kevlin Henney
コードレイアウトの重要性 by Steve Freeman
プログラマは仕事の時間を、実際にコードをタイプすることよりも、コードを探すことと読むことに費やしている、そんな調査結果もあるようです。
僕自身、実際にソフトウェアをメンテナンスする中で、読む方が多いと経験しています。
読む方が多いコードに対して、「デフォルト引数を使うことは有効なのだろうか?」と疑問を持ちつづけました。そして、上記の理由から、2018年8月現在の自分の考えでは「使わない方がコードを読みやすい」という考えです。
備考
記事執筆者の記憶力はあまりよくありません。短期記憶は5かもしれません。
そういう人でも読みやすいソースコードは何か、を日々考えています。
C++のtemplateやoverloadをうまく使うことで「それぞれのセンサーの通信速度は何か?」を複数台(例:10台)に対して2-3秒で一覧する方法があれば、知りたいと思います。
また、デフォルト引数を使うことで、ソースリーディングはこのように効率化する、ということがあれば知りたいと考えています。
注記: 記事執筆時点の考えなので、もっと良い方法があれば、考え方を反転することもあります。