GCC:重複定義(Multiple Definition)を許可するオプションを関数単体試験に利用する
このブログでは、現在「GCC:関数重複定義(Multiple Definition)を-z muldefsで許可する - プログラミングなどなど」が見られている回数が圧倒的に多く、全体の約半分を締めています。個人的には使用することが無かったため、なぜ、こんなに見られるのだろうかと気になっていました。そんな中、関数単体試験の際に役立つケースがあったので紹介したいと思います。(やっていることは前の記事と違いはありません。)
以下のような状況を想定しています。
targetModule.cに含まれるtargetFunc関数に大規模な修正を入れることになりました。その際に、同一モジュール内に含まれる長く、複雑な関数longFuncの呼び出しが追加されました。targetFuncの関数単体試験を実施したいのですが、longFuncが同一モジュールに含まれており、邪魔になっています。しかし、別モジュールへの分離も事情により行うことができません。
どの様に役立ったかというと、関数単体試験向けのlongFuncを別モジュールに用意し、リンク時に-z muldefsを使用することで、既存のlongFuncが動作しないようにしました。
targetModule.h
#ifndef TARTGET_MOD #define TARTGET_MOD int longFunc(int x); int targetFunc(int x); #endif
targetModule.c
#include <stdio.h> #include "targetModule.h" /* 長く複雑な関数 */ int longFunc(int x) { printf("長く、複雑な関数!\n"); return x; } /* 修正しテスト対象となる関数 */ int targetFunc(int x) { /* 修正色々 */ /* 同一モジュール内の長く、複雑な関数の呼び出し。*/ int ret = longFunc(10); /* 修正色々 */ return ret + 10; }
test.c
#include <stdio.h> #include "targetModule.h" int main(void) { int ret = targetFunc(5); printf("結果 : %d\n", ret); return 0; }
実行(通常)
$ gcc -Wall targetModule.c test.c $ ./a.out 長く、複雑な関数! 結果 : 20
関数単体試験用のモジュール(test.cに含める方法もあり)
#include <stdio.h> int longFunc(int x) { printf("単体試験用の関数!!\n"); return x; }
実行(スタブ版)
リンク順序には注意します。stub.cに定義した単体試験用のlongFuncが有効になるようにtargetModule.cより前に指定しています。
$ gcc -Wall -z muldefs stub.c targetModule.c test.c $ ./a.out 単体試験用の関数!! 結果 : 10
これまでは、デバッガなどを使って行っていた試験が自動化できました。