組み合わせテストケース生成ツール 「PictMaster」 とソフトウェアテストの話題 -22ページ目

「ペアワイズ法を使ったテスティングワークショップ」が開かれます

5月24日(土)に東京・池袋で表記のワークショップ(勉強会)が開かれます。主催者の許可を得てお知らせします。

この勉強会は開発者同士で一緒に学びあうという目的で行なわれるもので、テストの専門家というよりはテスト初心者、開発者の方に向いていると思います。講師から教わるという受け身の形ではなく、対等な立場の個人が集まってワイワイガヤガヤしながら行なう勉強会です。

PictMasterを使用してのPairwise法(all-pairs法)の実習も行います。私は参加できませんが、「ペアワイズ法を使ったテスト」に興味のある方は参加されてみてはいかがでしょうか。

他の会社の人と一緒に勉強会を行なうという機会はなかなかあるものではありません。普段の日常生活では得られない新しい発見や新しいつながりがきっと得られることでしょう。

詳細は以下のサイトをご覧下さい。

http://pistudy.doorkeeper.jp/events/11043

1980年代前半のパソコン自作

今では一頃より下火になったようですが、自作PCが盛んに話題にのぼるようになりました。自作PCというと私の場合は1980年代前半の頃のことになります。今回は当時のことを取り上げてみます。

当時は、パーソナルコンピュータという言葉がようやく広く知られるようになった時代です。NECのPC8001や富士通のFM-8といったマシンが有名でした。そのころのPC自作というと、「ワンボードコンピュータ」の自作ということになります。1枚の基板にICやLSI、CPUを載せてICのピンの間をケーブルで半田付けします。学習用にはいいかもしれませんがあまり興味が湧きませんでした。

1983年にトランジスタ技術というハードウェアの専門月刊誌に「ゼロから作るマイクロコンピュータシステム」という連載記事が掲載されました(記事の名称は正確でないかもしれません)。その記事では毎回1つの基板を取り上げて解説し、約2年程度でフロッピーディスク(FD)を備えたDOSベースで動作する「マシン」を自作するという内容でした。これには多いに興味を惹かれました。最初はスイッチでRAM上に命令を書き込む段階から、最後にはDOSで当時一定のシェアを占めていたCP/Mマシンまで作り上げるという連載記事です。最終的に10枚余りのユニットボードをシステムバスにつなぎ、1つのラックに収容する形になります。このまさに「ゼロから作る」DOSシステムという方針がとてもユニークでした。

現在の自作PCは、CPU、HDD、光学ドライブ、マザーボード、電源、ケースを買ってきて「組み立てる」ことを指していますが、当時の自作PCはICひとつひとつの買い出し、IC間の配線、ROMライタの自作、モニタ(ディスプレイのモニタではありません)のプログラミング、BIOSのプログラミングと、必要な作業量が半端ではありません。帰宅して空いた時間に自作してという風にすると完成するまで2年ほどはかかります。TTL-IC規格表と回路図を見ながら膨大な量の半田付けを行なったのはなつかしい思い出です。

1つのユニットボードは10cm×15cmくらいの大きさで、その上に5列までICやLSIを配置することができるようになっています。ユニットボードにはICのピンの間隔に合わせて無数の穴が開いており、裏側の穴の周囲には銅版がプリントされていて、ICのある表の側から細いケーブルを差してICのピンと半田付けを行ないます。ユニットボードの端には50ピンの端子が印刷されており、これをボードソケットに指し、ソケットはシステムバスに接続します。システムバスの長さは45cm、これに16枚のユニットボードが挿入可能で1つのラックに収容する形になります。ラックはそれにあった大きさのケースに収容し、ケース背面に5V、12Vなどを供給する電源ユニットと各種IOポートの接続コネクタを取付ける形になります。

この取付け作業は板金加工そのものです。ケース前面は16ビットのアドレスと8ビットのデータの表示を行なう24個のLEDの穴開けと、同じくアドレス、データの指定を行なう24個のスイッチの穴開けが必要です。ご丁寧にもケースは2重になっていて2度同じ穴開けを行なう必要がありました。これだけで100回近くの穴開けが必要です。穴開けはハンドドリルで行ないます。四角の穴開けが必要な場合は四隅に穴を開け、その間を糸金切り鋸で切り、最後に金ヤスリできれいに仕上げます。糸金切り鋸が通せない場所に四角の穴を開ける場合は大きな穴が開けられる専用の工具でいくつか穴を開け、金ヤスリできれいに仕上げます。ケースの天板と下板は鉄製ですが、それ以外はアルミ製なので削りやすいのです。

一番大変だったのがシステムバスの配線でした。50ピンのソケットが16個あり、それぞれの間を接続する必要があります。システムバスの配線だけで1500回に上る半田付けを行ないました。単純作業が何日も続き、とても疲れました。

「ゼロから作る」マイコンシステムなので、最初はプログラムがありません。ではどうやってプログラムを書くかというと、ケース前面のスイッチを使ってアドレスとコードを2進数で指定し、書き込みスイッチの押下でRAM上の指定されたアドレスに指定されたコードが書き込まれるようにします。こうして「モニタ」プログラムを書き込みます。RAMはSRAMでバッテリでバックアップされています。電源をオンしたり、リセットスイッチを押したときにこのモニタプログラムが走るようにプログラムしておきます。

モニタプログラムには、カセットテープにプログラムをバックアップしたり、その逆にカセットテープからプログラムをロードしたりできるようにする機能も追加します。この機能にはSIO(シリアルコントローラ)が必要ですが、そのユニットボードも作成します。この時点でCPUボードとSIOボードが完成します。パソコン自作にはオシロスコープが必須です。クロックがきれいにでているかなどを確認するにはオシロスコープがなければ始まりません。このころ安かったリーダー電子製の20MHzオシロスコープを購入しました。

続いてROMライタ機能を追加します。モニタプログラムをROMに書き込んでROMベースで動作できるようにします。この機能にはPIO(パラレルコントローラ)が必要ですが、そのユニットボードも作成します。ROMに書き込むプログラムもROMに書き込みます。

ここまでくると次はキーボードとCRTディスプレイを使えるようにします。モニタプログラムにこれらのデバイスのコントロールを行なうプログラムを追加し、ROMに書き込んでROMを差し替えます。この時点でCRTボードが追加になります。キーボードインタフェースはPIOユニットボードに追装します。続いてプリンタを接続できるようにします。これはプリンタ専用にもう一つPIOユニットボードを追加することになります。CRTコントローラのプログラミングでは少してこずりました。何かスクロールした拍子にCRTの端っこに1つ余計な文字がでるのです。時間はかかりましたがどうにか原因を突き止め、解決することができました。

次はいよいよDOSの移植に移ります。DOSはデジタルリサーチ社のCP/Mを購入しました。CP/Mを購入するとフロッピーディスクドライブ(FDD)をコントロールするBIOSプログラムが含まれています。このプログラムを使用するFDDに合わせてカスタマイズします。当時すでに5インチのFDが主流でしたが、CP/Mが8インチFDで提供されるので、このときはアルプス電気の8インチドライブユニットを使用しました。CP/MのBIOSは片面用でしたが、単密度ですが簡単な変更で両面用に改造することができました。このFDDを接続するFDC(FDコントローラ)ユニットボードを追加します。こうしてDOSベースで動作するようになると、Cコンパイラなどを使用することができるようになりました。今では想像もできないでしょうが、数十KBのRAM上でフルセットのCコンパイラが動作するのです。しかもコンパイル対象のソースファイルのサイズに制限はありません。コンパイル時間さえ気にしなければかなりのステップ数のプログラムもコンパイルできてしまいます。このコンパイラは当時の業務で多いに活躍しました。この頃のコピーガードは「素朴」で、逆アセンブルするとその判定命令が簡単に分ってしまいました。あとはその命令をNOP命令である0でクリアし、ディスクに書き戻せばコピーフリーのコンパイラができてしまいます。今、こういうことはやってはいけません。

最初にCP/Mを移植したときは56K CP/Mといって、64KBのRAMのうち、最後の8KBをDOSで占有する方式でした。これでは少ないRAMがもったいないので、BANK切替えを導入してBIOS部分をROMに書き込み、RAMとのバンク切替えで64KBをフルにCP/Mで使用できるように改造しました。

CPUはザイログ社の8ビットで4MHzのクロックで動作するZ80です。これをクロックを6MHzに上げて6MHzで動作可能なZ80Bに変えたところ、使っているうちに突然暴走するようになりました。最初は原因が分らなかったのですが、そのうち自宅の冷蔵庫のサーモスタットがオンオフするときに暴走することが分りました。サーモスタットのオンオフで発生するノイズが暴走の原因だったのです。

AC電源の引き込み部分にフェライト製のノイズフェルタを入れてみたのですが改善しません。こういうノイズ対策は素人には難しいものです。結局、試行錯誤の末、長さ45cmのシステムバス部分の表面にビニール製のシートをかけ、その上からアルミホイルで覆うことで解決することができました。

こうしたアナログ的なトラブルの解決は難しいですが、デジタル回路そのものは基本さえ押さえれば、誰が作っても同じように動作するものです。マイコンシステム作成の際に身につけたデジタル回路の知識が、その後の組込みソフトの開発において何度も役に立ちました。

今では現代版「ゼロから作る」マイコンシステムは作れないかもしれません。ワンボードマイコンシステムはありますが、個々のチップレベルで個人が入手できるものは年々少なくなっているようです。それにOSが最大のネックになりそうです。

今から思い返すと、例え今同じ環境が再現できたとしても、とてもできる気がしません。あの頃はパワーにあふれていたように思います。

Myersの三角形問題を解く

今やソフトウェアテストの古典ともいえる「Myersの三角形問題」のテストケースを、PictMasterを使用したデシジョンテーブルで作成してみることにします。

Myersの三角形問題とは、3辺の長さをあらわす3つの整数を読み、不等辺三角形、二等辺三角形、正三角形のどれなのかを判別して表示するプログラムのテストケースを書くというものです

この問題をテストするテストケースには様々な考え方があり、数件から数百件までと大きな幅があります。これらの違いは、ブラックボックステストかホワイトボックステストか、コマンドベースかGUIベースか、防御プログラミングかそうでないかなどの違いに起因するものです。ここではブラックボックステストでコマンドベースで防御プログラミングでない場合を考えてみます。

防御プログラミングとは、例えば入力できる文字は半角数字のみに限られるなどの「防御」の仕組みがプログラムとして組み込まれていることです。

このデシジョンテーブルの条件はどうでしょうか。色々な考え方がありますが、私が考えた条件とその値は次の通りです。

条件
A + B A + B < C, A + B = C, A + B > C
B + C B + C < A, B + C = A, B + C > A
C + A C + A < B, C + A = B, C + A > B
A = B Yes, No
B = C Yes, No
C = A Yes, No

A、B、Cは辺の長さです。

動作とその値は次の通りです。

図形の種類 正三角形, 二等辺三角形, 不等辺三角形, 三角形でない

3つの辺の長さが与えられたとき、それが三角形を構成できる辺であるのかを判定するルールは次の通りです。

(1) 3つの辺のどの2つの辺についてもその長さの合計は残りの辺の長さより長い

この(1)が成り立つならば、それは三角形であるということができます。成立しなければそれは三角形ではありません。
次に三角形の種類を判定するルールは次の通りです。

(2) 3つの辺の長さが等しいなら正三角形
(3) 前項(1)を満足し、かつ2つの辺の長さが等しいなら二等辺三角形
(4) 前項(1)を満足し、かつ3つの辺の長さが異なるなら不等辺三角形

この他に、異常ケースとして次のテストケースが必要です。

 長さが0の辺が含まれている。
 長さがマイナスの辺が含まれている。
 長さが扱える最大値を超える辺が含まれている。
 長さが小数点の辺が含まれている。
 長さが文字の辺が含まれている。
 長さがNullの辺が含まれている。
 辺の数が2つ以下。
 辺の数が4つ以上。

これらのどれかがYesの場合は「三角形でない」という動作になります。すべてがNoであれば正常、準正常の条件で動作が決まることになります。「~の辺が含まれている。」は3つの辺について判定する必要があるので×3倍したテストケース数になります。従ってこの異常ケースでのテストケース数は6×3+2=20件ということになります。

異常ケースは単独のテストでできるので、デシジョンテーブルには含めずに、正常(三角形のどれか)、準正常(三角形でない)の条件でデシジョンテーブルを作成しました。

1

2


制約1~3では、ある2辺の合計の長さが残りの辺の長さと比較して短いか等しい場合、それ以外との2辺の合計長さは残りの辺の長さより必ず長くなるということ(制約の1行目~3行目の定義)、ある2辺の合計の長さが残りの辺の長さと比較して短いか等しい場合、そのある2辺の長さが等しい場合があり得るが、その場合それ以外との2辺の長さは必ず異なること(制約の4行目~6行目の定義)を定義しています。文章が分かりにくいですが、実際にいくつかのパターンで制約指定のとおりの結果になるか調べてみると理解できると思います。

制約4では正三角形の条件を、制約5~7では二等辺三角形の条件を、制約8では不等辺三角形の条件を定義しています。この制約指定ではすべての条件に特定の1つの値が明記されているので、各動作に該当する組み合わせは1つしか存在しないことになります。

制約9~11では、三角形でない場合の条件を定義しています。ここでは先に挙げたルール1に反する条件を指定しており、これに該当する場合は三角形ではありません。これは制約1~3の影響を受けます。

組み合わせるパラメータ数に条件の数=6を指定して生成を行なうと次の17件のテストケースが得られます。

1


このテストケースに異常ケースを追加すると、Myersの三角形問題のテストケース数は17+20=37件となりました。この件数は最初にあげた前提条件でのものなので、前提条件が違えばこれ以外のテストケースであってかまいません。

厳密に言えば、異常ケースのテストケースは20件で十分という訳ではなく、境界値+1と境界値+2のテストケースが必要になるかもしれません。

Myersの三角形問題は、条件の決定が極めて重要です。これがうまくないと、テスト漏れが起きたり、冗長なテストになったりします。

Myersの著作「ソフトウェアテストの技法」にこの問題が掲載されており、そこでの回答は次のようになっています。

Myersの三角形の解答:

<有効な三角形となるテストケース>

1.有効な不等辺三角形となる値のセット
2.有効な正三角形となる値のセット
3.有効な二等辺三角形となる値のセットで a = b の場合
4.有効な二等辺三角形となる値のセットで b = c の場合
5.有効な二等辺三角形となる値のセットで a = c の場合

<有効な三角形とならないテストケース>

6.長さが0の辺がある場合
7.長さが負の値の辺がある場合
8.整数でない辺がある場合
9.3辺が0(無効な値で3辺が等しい場合を代表している)
10.2辺の和がもう1辺と等しくなる値のセットで a = b + c の場合
11.2辺の和がもう1辺と等しくなる値のセットで b = a + c の場合
12.2辺の和がもう1辺と等しくなる値のセットで c = a + b の場合
13.2辺の和がもう1辺より小さくなる値のセットで a > b + c の場合
14.2辺の和がもう1辺より小さくなる値のセットで b > a + c の場合
15.2辺の和がもう1辺より小さくなる値のセットで c > a + b の場合

16.テストの期待結果をテストケースに書いていたら+1点とする。

これは全部で16件になります。ここでは異常ケースが1つの辺についてしか言及されていないので不十分だと思われます。異常ケースを×3倍して数えると全部で21件です。ここでは16.は各テストケースに含まれているものとして数えているので除外しています。

Myersの記述では、三角形とならない場合に辺の長さ a = b、b = c、c = a との組み合わせが考慮されていません。そのため、三角形とならない場合の準正常ケースではテストケース数が6件となっています。私がデシジョンテーブルを使って生成したテストケースでは、2倍の12件となっています。これは私の場合に辺の長さが等しい場合 a = b、b = c、c = a との組み合わせも考慮しているためです。ソフトウェアがどのようにプログラミングされているか分からないブラックボックステストでは、一般的にプログラム構造に何らかの前提条件を置くべきでないということが言えます。ただし、テストケース数が膨大になってテストにかかるコストとバグを見逃すリスクとの兼ね合いで、コストが大きく、リスクが小さいなら一定の前提条件を置くことは認められるべきでしょう。この三角形問題ではテストケースはそれほど多くはないので、私はプログラム構造に一切の前提条件を付けずにテストケースを決めています。

実際問題、三角形とならない場合に2辺の長さが等しいケースでバグがあり得るかというと、ほとんどの人のプログラミングでは、2辺の長さの比較より先に2辺の和がもう1辺より長いかを判定すると考えられます。そのため、私が追加した条件はほとんどの場合意味がないでしょう。ですがプログラミングのやり方は自由ですからどのようにプログラミングされているかはわかりません。条件の組み合わせは可能ですから可能な組み合わせはテストケース数が多すぎなければやった方がよいでしょう。

三角形でない場合に2辺の長さが等しい場合といずれも等しくない場合との組み合わせを、Myersはなぜテストケースに含めなかったのでしょうか。そこまで思いつかなかったということがありそうな理由です。もちろん、プログラム構造上関係ないと考えた可能性も否定できませんが、そうするとブラックボックステストではなくなってしまいます。テスト技法としてデシジョンテーブルを用いなかったからというのが最もありそうな理由です。デシジョンテーブルは1980年代に普及し始めましたが、Myersの著作「ソフトウェアテストの技法」が出版されたのが1979年(*1)だからです。

Myersの三角形問題をデシジョンテーブルで解こうとすると、それには必ずa = b、b = c、c = a の条件が含まれるはずです。デシジョンテーブルテストはすべての条件の全数組み合わせテストなので、当然三角形でない場合に2辺の長さが等しい場合といずれも等しくない場合との組み合わせがテストケースに表れるはずです。ただし、特定のプログラム構造を前提条件として考え、結果に影響がないとしてこの条件を無視する人も出てくるでしょう。ここではそうしない場合を考えてみます。そうすると、異常ケースを除いた各条件をYes、Noの2値で表現すると、2^12 = 4096通りのデシジョンテーブルになります。

ここまで大きなデシジョンテーブルになると人手で正確なデシジョンテーブルを作成することが困難になります。こうした場合、複雑な制約を分かりやすく表現できる「制約表」を備えた組み合わせテストツールを用いることで正確に早く正しいデシジョンテーブルを作成することができます。今回のMyersの三角形問題を解くデシジョンテーブルは、その好例と言えそうです。

ここで示したテストケースは正解とは限りません。考え違いや見落としがあるかもしれませんのでご承知おきください。なお、この記事内容は適宜変更されることがあります。


*1: "A Lifelong Software Tester's Blog"(生涯一テスター)  最初の話題は三角形問題  より

※ 2014年5月16日 異常ケースのテストケース数を8件から20件に修正しました。Myersの回答と比較した考察を追記しました。

圧縮されたデシジョンテーブルしか作成されないCFD技法の使用は要注意

原因から結果に向う矢印で論理関係を表現し、それをもとにデシジョンテーブルを作成する技法としてCFD技法が知られています。CFD技法は、その名が示す通り、原因から結果に向う流れ線で表現されます。このとき、CFDから作成したデシジョンテーブルをそのままテストに用いると、テスト漏れの可能性のあるデシジョンテーブルができてしまいます。

電話をかけると通常は自分の電話番号が相手に通知されます。これを電話会社との契約によって通知しないようにすることができます。また相手の電話番号の前に特別なダイヤルを付加して電話をかけることによって、相手に自分の電話番号を通知するかしないかを指定することもできます。

この発信者番号通知処理の仕様は次の通りです。

1.電話会社との契約で「通知する」を選択していると自分の電話番号が相手に通知される。
2.電話会社との契約で「通知しない」を選択していると自分の電話番号が相手に通知されない。
3.電話をかける際に相手の電話番号の前に186を付加すると電話会社との契約にかかわらず自分の電話番号が相手に通知される。
4.電話をかける際に相手の電話番号の前に184を付加すると電話会社との契約にかかわらず自分の電話番号が相手に通知されない。

この仕様から発信者番号通知処理について次のルールが得られます。

1.通知する
 (1) 電話会社との契約が「通知する」でかつ付加ダイヤルなしで電話をかける。
 (2) 186を付加して電話をかける。
2.通知しない
 (1) 電話会社との契約が「通知しない」でかつ付加ダイヤルなしで電話をかける。
 (2) 184を付加して電話をかける。

このルールから次の原因と結果が求められます。

原因:
電話会社との契約
 通知する、通知しない
付加ダイヤル
 186、184、なし
結果:
発信者番号
 通知する、通知しない

これをもとに作成したCFDを次に示します。

1


このCFDをもとに次のデシジョンテーブルが作成されます。


2


このデシジョンテーブルは最初から圧縮されていてルール数は4となっています。このデシジョンテーブルで次のプログラムをテストすると、テスト漏れが起きてしまいます。なぜなら、このプログラムが結果を決めるルートは6つありますが、作成したデシジョンテーブルでは4つしかテストしないからです。残りの2つのルートはテスト漏れとなります。

if 電話会社との契約 = 通知する then
if 付加ダイヤル = なし then
return = 通知する
else
if 付加ダイヤル = 186 then
return = 通知する
else
return = 通知しない
end if
end if
else
if 付加ダイヤル = なし then
return = 通知しない
else
if 付加ダイヤル = 186 then
return = 通知する
else
return = 通知しない
end if
end if
end if

このプログラムではif文が5個と多いため、多くの人は3個で済む次のプログラムを書くと思われます。このプログラムなら圧縮された4つのルールのデシジョンテーブルでもテスト漏れは起きません。

if  付加ダイヤル = なし then
if 電話会社との契約 = 通知しない then
return = 通知しない
else
return = 通知する
end if
else
if 付加ダイヤル = 186 then
return = 通知する
else
return = 通知しない
end if
end if

ですが、少なからぬ人が最初のプログラムを書く可能性は無視できません。テスト漏れを無くすには、圧縮されていないデシジョンテーブルを用いる必要があります。CFD技法で任意値となっている圧縮された「ー」の部分を拡張して実際の値を記入し、6件のデシジョンテーブルとすればよいのです。

論理構成によっては安全に圧縮できる場合がありますが、この例の場合は圧縮されていないデシジョンテーブルを用いる方が良いと思われます。ここで書いたことは原因結果グラフにも当てはまります。

1980年代前半のオブジェクト指向ブーム

今回は昔の話しをしましょう。オブジェクト指向プログラミングはいまでは当たり前のように行われていますが、オブジェクト指向の最初のブームが起きたのは1980年代前半でした。オブジェクト指向プログラミングに関する多数の書籍が刊行され、一大ブームが起きたのです。当時すでにいくつかのオブジェクト指向プログラミング言語がありましたが、その中でも最初のオブジェクト指向言語であるSmalltalkは別格でした。このプログラミング言語はすべてがオブジェクトであり、数字もオブジェクトという徹底ぶりです。

1+2という演算も、1というオブジェクトに+というメッセージを送信し、その引数として2というオブジェクトがあるという風に内部で処理されます。メソッドとメッセージの関係はダイナミックバインディングで実行時に決定されます。Smalltalkは仮想マシンが解釈する「バイトコード」で実行されるインタプリタ言語です。また実行環境に最低でも1MB以上のメモリ量を必要とし、当時のパソコンでそれだけのメモリを搭載できるものはなく、大量のメモリを搭載したワークステーションでしか実行できませんでした。当時はSmalltalkはまだ一部好事家のあこがれの対象だったのです。

1986年にMacintosh Plusが発売され、このマシンが1MBのメモリを搭載していました(後に4MBまで拡張)。もちろんSmalltalkに必須のビットマップディスプレイとマウスを備えていました。当時からMacファンであり、Smalltalkファンでもあった私は、Macintosh Plusを購入後さっそく富士ゼロックスから発売されていたSmalltalk-80を購入したのはいうまでもありません。当時Smalltalk-80はウン十万円もしましたが、Mac上でフルスペックの本物のSmalltalk-80が動作したときの感激は今でも忘れられません。

純粋なオブジェクト指向言語であるSmalltalkは開発環境(これもSmalltalkで書かれている)と一体となっており、その開発環境上でしかプログラムが動作しませんでした。スタンドアロンで動作するSmalltalkのソフトウェアは作れなかったのです。またすべてをオブジェクトとしたことによる実行速度の遅さなどのため、次第に注目されなくなっていきます。ですがSmalltalkのオブジェクト指向の思想がその後のプログラミング言語に大きな影響を与えたことは、現在の数多くのオブジェクト指向言語をみれば明らかです。MVCモデルの考え方はSmalltalkから生まれたものです。それぞれ何らかの形でSmalltalkの影響を受けています。

1986年頃になると、組み込みシステム上でもオブジェクト指向言語の適用が試みられるようになりました。月刊インタフェース誌(今ではInterfaceという名称になっているようです)でオブジェクト指向の特集が組まれたのもこの頃です。この時の特集の内容はあらかた忘れてしまいましたが、C言語の構造体定義を用いてクラスを定義し、そこから構造体のサイズ分のメモリをGetしてインスタンスとするといった内容でした。

当時の私はこれを参考にしてCのマクロ定義で構造体を定義し、メッセージ送信もマクロの記述でできるようにしました。構造体の定義を工夫することでスーパークラスも定義できます。継承の機能そのものはオブジェクト指向とは無関係ですが、あれば便利なものです。メッセージ送信はダイナミックバインディングで行います。メッセージに対応するメソッドの決定はハッシュ関数を用いて高速に行えるようにしました。Selfへの送信やSuperへの送信ができます。C言語のマクロ定義をフルに活用することで割と簡単にオブジェクト指向風なプログラムの記述が可能となりました。

クラスへnewメッセージを送信すると、返り値としてイスタンスのポインタを返すようにします。クラス階層は各クラスの構造体定義ファイルにスーパークラスの構造体定義ファイルをインクルードするように記述することで実現できます。これが最上位のObjetクラスの構造体定義ファイルまで下から上へ次々とインクルードされてコンパイルされることになります。この
オブジェクト指向風C言語はネイティブコードで動作するので高速です。ただし、実行するメソッドは実行時にハッシュテーブルで決定するのでその部分は時間がかかりますが。クラス変数やインスタンス変数も使えます。メソッドのオーバーライドも可能です。ポリモーフィズムも実装可能です。不要となったインスタンスの解放はプログラマの責任になります。さすがに多重継承までは作り込みませんでしたが、オブジェクト指向言語としての特徴はほぼすべて実現できました。

こうしてオブジェクト指向風の記述ができるようにしたC言語で様々なオブジェクトを定義し、例えばクラス「財布」を定義し、そのインスタンスを生成して、お金の出し入れや残高の表示をインスタンスへのメッセージ送信という方法で行なって遊んだのは楽しい思い出です。