プログラマ(SEも含む)の性賢説と性愚説というのを考えた。
どちらの立場をとるかによって、テストコードの意味合いが変わってくる。
■性賢説
プログラマは、正しく完璧な設計と実装を行うことが可能である。
そのコードはメンテナンス性も良く、後日の機能追加、仕様変更も容易である。
テストコードは、その完璧な実装に近づけるための手助けとなるためのものである.
■性愚説
プログラマは、正しく完璧な設計と実装を行うことはできない。
そのため、後日の機能追加、仕様変更時にコードを少なからず書き換える必要がでてくる。
最悪の場合はコードを全て書き直す必要がある。
テストコードは、その不完全なコードを少しでも良くするためものである。
----
性愚説をもう少し考えると、以下の結論がでてくる。
テスト対象のコードは大幅に書き換えられる。時には外部公開APIも変わる可能性がある。
→テストコードはテスト対象のコードが変わっても使える様にしておくべきである。
→テストコードは、再利用できる部分とできない部分に分けておくべきである。
例えばAPIのテストを行うときには、以下の二つのコードがある。
1. テストに使用するテストパターン
2. テスト対象の関数の呼び出し
このうち、1.は再利用が可能なので、2.とは別にしておくのが望ましい。
google-code-prettify
2009-12-10
x86のmisalignアクセス時に例外を起こす方法
x86ではmisalignアクセス時でも、例外を起こさずにアクセスする事ができる。
例えば次のコード
は、misalignアクセスであり、多くのプロセッサでは例外が発生する。
x86でも同様に例外を発生させてやるには、EFLAGSレジスタのbit18、AC(Alignment Check)ビットを1にしてやれば良い。
gccのインラインアセンブラの例。
これが何の役に立つかと言うと、
・misalignアクセスで例外が発生するプロセッサ上で動作させるコードを作成したい。
・でも、そのテストはx86(Linuxなど)上で行いたい。
という場合。
参考:
X86 Assembly/X86 Architecture
Mis-aligned pointers on x86
GCC Inline Assembler
09/12/11 追記:
この機能、実はあまり使えないような気がしてきた。
なぜなら、glibcはACが0である事を期待したコードになっていて、ACを1にするとglibcの関数で落ちるから。
例えば次のコード
long *p;
char buf[32];
p = (long*)&buf[1];
*p = 0;
は、misalignアクセスであり、多くのプロセッサでは例外が発生する。
x86でも同様に例外を発生させてやるには、EFLAGSレジスタのbit18、AC(Alignment Check)ビットを1にしてやれば良い。
gccのインラインアセンブラの例。
__asm__ __volatile__ (
"pushf\n"
"\tpopl %%eax\n"
"\tor $0x00040000, %%eax\n"
"\tpushl %%eax\n"
"\tpopf\n"
:::"%eax");
これが何の役に立つかと言うと、
・misalignアクセスで例外が発生するプロセッサ上で動作させるコードを作成したい。
・でも、そのテストはx86(Linuxなど)上で行いたい。
という場合。
参考:
X86 Assembly/X86 Architecture
Mis-aligned pointers on x86
GCC Inline Assembler
09/12/11 追記:
この機能、実はあまり使えないような気がしてきた。
なぜなら、glibcはACが0である事を期待したコードになっていて、ACを1にするとglibcの関数で落ちるから。
2009-12-06
pmccabe - プログラムの複雑度を測定する
pmccabe。
CやC++のプログラムの循環的複雑度を計測してくれるツール。
改行コードがCRLFのファイルにpmccabeをかけると、以下のようなエラーがでる。
これを防ぐには、pmccabeに通す前にソースコードの改行コードをLFに書き換えるか、pmccabe自体を以下の様に変更すれば良い。
CやC++のプログラムの循環的複雑度を計測してくれるツール。
改行コードがCRLFのファイルにpmccabeをかけると、以下のようなエラーがでる。
"a.c", line 187: too many }'s
これを防ぐには、pmccabeに通す前にソースコードの改行コードをLFに書き換えるか、pmccabe自体を以下の様に変更すれば良い。
--- pmccabe.h.orig 2009-12-06 23:36:37.000000000 +0900
+++ pmccabe.h 2009-12-06 23:26:15.000000000 +0900
@@ -133,7 +133,7 @@
stats_t *stats_pop(stats_t *sp);
void stats_accumulate(stats_t *sp);
-#define ISSPACE(c) ((c) == T_NCNULINE || (c) == '\n' \
+#define ISSPACE(c) ((c) == T_NCNULINE || (c) == '\n' || (c) == '\r'\
|| (c) == '\t' || (c) == ' ')
#define ISIDENT1(c) (((c) >= 'a' && (c) <= 'z') \
2009-12-04
Cで、constなポインタからconstをはずす方法
constなポインタからconstをはずすキャストをすると、コンパイラのwarningが出る事がある。
明示的にキャストしているから問題ないような気もするのだが、warningは出てしまう。
一度longにキャストするという手もある。
しかしこれだと、「ポインタのサイズとlongのサイズは同じなのか?」問題があり、スッキリしない。
以下のようにunionを使うと、コンパイラをだまらせる事ができ、しかもスッキリと問題が解決する。
const void *p;
void *p2;
p = xxx;
p2 = (void*)p; ←ココ。
明示的にキャストしているから問題ないような気もするのだが、warningは出てしまう。
一度longにキャストするという手もある。
p2 = (void*)(long)p;
しかしこれだと、「ポインタのサイズとlongのサイズは同じなのか?」問題があり、スッキリしない。
以下のようにunionを使うと、コンパイラをだまらせる事ができ、しかもスッキリと問題が解決する。
union {
void *vp;
const void *cvp;
} u;
u.cvp = p;
p2 = u.vp;
登録:
投稿 (Atom)