C/400

44. 条件つきコンパイルによるリリース/ディバッグの分離

ANS-C によって開発する目的のひとつは実行速度を上げたいということでもある。
しかし、リリースするオブジェクトに大量のログアウトやディバッグ命令が含まれていると
折角の C/400 で開発しているにもかかわらずオブジェクトは、巨大なものとなり、
各命令で「ディバッグ・モードであるときは ...」の多数の判断命令の演算を通過させなければ
ならない。大量の printf 関数が使用もしないのに含まれてしまうことになる。
Microsoft VC++ の開発の経験のある人であれば、リリース用とディバッグ用のモジュールを
分離してリリース用にはディバッグ命令を入れないようにすることができれば解決すると
望むはずである。
ここでは C/400 による、その手法を紹介しよう。
UNIX 等の他のプラットフォームでは条件つきコンパイルは珍しくない。
他のプラットフォームからの移植ではプラットフォーム個別のコンパイル定義を用意しておいて
コンパイル定義によって一気に複数のすべのモジュールをコンパイルするという方法が
採用されている。Perl も、この方法によって様々なプラットフォームへの移植を行っており
今、流行のPHP や Rubby をソースから移植しようとするツワモノがいたとすれば
ここで紹介する条件つきコンパイルを理解することができれば、その基礎となり移植への道も
開けてくるであろう。

【 サンプルC/400 】
0001.00 #include <stdio.h>              
0002.00 #include <stdlib.h>             
0003.00 #include <string.h>             
0004.00                                 
0005.00 void main(void){                
0006.00    char buff[128];              
0007.00 #ifdef DEBUG                    
0008.00    printf("buff = %s\n", buff); 
0009.00 #endif                          
0010.00 }                               
【 解説 】

#ifdef DEBUG 〜 #endif までのステートメントは コンパイラーで 条件 DEBUG が指定されている
場合にだけ有効となり、コンパイル・ソースに含まれるが DEBUG が定義されていない場合は
それらのステートメントは含まれることはない。
条件 DEBUG を定義してコンパイルするには

CRTBNDC PGM(MYLIB/TESTDBG) SRCFILE(MYSRCLIB/QCSRC) DEFINE('DEBUG=1') AUT(*ALL)

のようにしてコンパイルするだけである。
生成するオブジェクトをディバッグ用とリリース用との別々に作成すれば
実際の実行はリリース用モジュールによって実行されるので不要なディバッグ命令も
含まれることは無く、理想的なオブジェクトを作成することができる。
実際、EnterpriseServer Ver5.0 の AutoWeb は、このようにしてリリース用とディバッグ用の
オブジェクトが分離されている。
このことによって普段、ユーザーが使用するリリース用オブジェクトは不要なディバッグ命令や
ログ出力も含まれていないのでパフォーマンスの向上に繋がり、ユーザーは快適な操作ができるように
配慮されている。
もちろんリリース用はオブジェクト・サイズもディバッグ用に比べて小さなものに仕上がっている。
ユーザーの要求に応じていくとオブジェクトは益々大きなものとなり、やがでは動作自体が
遅くなってしまうことは製品として厳に避けたいものである。