C/400

20. すべてのOS/400リリースで通用するC/400を書くには?

C/400を使ってAPI関連のプログラムを作成しているとOS/400のリリースによって
異なる記述が必要になってくる場合がある。
それでは OS/400のリリース別に別々のソースを用意すればよいかというと
後々の保守の問題が発生する。
例えばある機能を追加したり、バグの修正などを行っても別のリリース用のソースを
修正するのを忘れてしまう場合があるからである。
ひとつのソースですべてのリリースにも対応できるように記述することはできないものであろうか?
その回答はC/400のコンパイラーに用意されている。

CRTCMOD のパラメータには「名前定義」というものがある。
ここに V4R4M0=1 のように定義するとコンパイラーはそれにあったソース部分だけを適切に
コンパイルしてくれる。
C/400ソースの中では

#ifdef V4R4M0                                             
    rc = pthread_create(&thread[i], NULL, do_child, (void *)newfd)
    rc = pthread_detach(thread[i]);                               
#else                                                             
    rc = pthread_create(&thread[i], NULL, do_child, (void *)&newfd
    rc = pthread_detach(&thread[i]);                              
#endif

のように記述すれば V4R4M0 という名前定義がある部分とそうでない部分のどちらかのソースの部分が
選択されてコンパイルされる。
例えば V3R2M0 から V4R3M0 までのマルチ・スレッドは POSIX スレッドであるし、V4R4M0 以降は
カーネル・スレッドであるので、リリース個別にソースを替える必要がある。
しかし EnterpriseServer の HTTPサーバーである「Alaska」はこのことを利用してひとつのソースで
複数のリリースのコンパイルに対応している。
この手法は CPAN の Perl ソースのコンパイルにも使用されている。
Perl はひとつのソースであらゆるプラット・フォームにも対応できるようにしているので、
この方法によってコンパイラーを制御しているのである。