読者です 読者をやめる 読者になる 読者になる

テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

(macro-of-inline report) 宣言を無条件でブロックの先頭に置いてはならない

以下のコードを考える. このコードは, "hoge" "hage"と出力する.

#include <stdio.h>
static inline void f(void) { puts("hoge"); }
static inline void g(void) { puts("hage"); }
typedef void(*func_t)(void);
int main(void) { f(); func_t f = g; f(); return 0; }

最初のf()が呼び出された時には, fはf(void)のことであるが, 次にリネームが起こったため, fはgのことになっている.

non-voidな関数をvoidに変換する時, int x = f()を, int x; x = f()に変形している. これは現在は無条件であるが,

「右辺がFuncCallの場合のみ」とするのが良さそうである. そもそも, FuncCall以外の場合では分離する必要がない. 例えば, int x = 0を分離する必要はない. gccで見ると, 分離したとしても同じアセンブリを吐いてるように見えるが, あらゆるコンパイラでそうかは分からないので, 出来ることならばやらない方がいい. また, 分離するとしてもやはり, 直前にinsertする方が良い. コードに無駄な変形を加えて, 動作が変わる紛れを作るのはやばい. Rubyテストを通そうと思うと, 安全に行かないとヤバい.