処理時間計測用マクロの例
2010年3月20日 お仕事C言語で処理時間計測用マクロをつくってみました。
関数マクロやdefineについてはhttp://www.c-lang.org/define.htmlを見てください。
/*
clock_macro.c
処理時間計測用マクロの例
*/
#include <stdio.h> /* printf */
#include <stdlib.h> /* EXIT_SUCCESS */
#include <time.h> /* clock */
#include <math.h> /* sin */
/*
処理時間の計測をしたいコードと
ループ回数を指定すると
処理にかかったプロセッサ時間を表示する
*/
#define CALC_CLOCK(code, n) { \
int i; \
clock_t t0 = clock(); \
for (i=0;i<n;i++) { code; } \
printf("%d\n", clock() - t0); \
}
#
int main(int argc, char *argv[])
{
int x = 1;
CALC_CLOCK(x = sin(x), 10000000UL);
return EXIT_SUCCESS;
}
関数マクロやdefineについてはhttp://www.c-lang.org/define.htmlを見てください。
/*
clock_macro.c
処理時間計測用マクロの例
*/
#include <stdio.h> /* printf */
#include <stdlib.h> /* EXIT_SUCCESS */
#include <time.h> /* clock */
#include <math.h> /* sin */
/*
処理時間の計測をしたいコードと
ループ回数を指定すると
処理にかかったプロセッサ時間を表示する
*/
#define CALC_CLOCK(code, n) { \
int i; \
clock_t t0 = clock(); \
for (i=0;i<n;i++) { code; } \
printf("%d\n", clock() - t0); \
}
#
int main(int argc, char *argv[])
{
int x = 1;
CALC_CLOCK(x = sin(x), 10000000UL);
return EXIT_SUCCESS;
}
条件付き取り込みについて調べてみました。
#if、#elif、#else、#endif等の
プリプロセッサ指令を使うことにより、
ソースコードの条件付き取り込みを行うことができる。
#if、#elifに続く取り込みを制御する式は
整数定数式でなければならない。
その式は、キャストを含んではならない。
define演算子を用いた、
defined 識別子あるいはdefined (識別子)という表現は可能。
この時、識別子がマクロ名として定義されていれば
制御式を1と評価する。そうでない場合は0と評価する。
制御式の評価結果が0以外ならば、
その間にあるソースコードはコンパイル対象となる。
制御式中のマクロ置換は、
(defined演算子のオペランドになるマクロ名を除く)
評価の前に行われる。
この変換で、字句definedが生成される場合の動作は未定義。
#ifdefと#ifndefは、それぞれ
#if defined 識別子、#if !defined 識別子と等価。
条件付き取り込みを入れ子にすることは可能。
#if、#elif、#else、#endif等の
プリプロセッサ指令を使うことにより、
ソースコードの条件付き取り込みを行うことができる。
#if、#elifに続く取り込みを制御する式は
整数定数式でなければならない。
その式は、キャストを含んではならない。
define演算子を用いた、
defined 識別子あるいはdefined (識別子)という表現は可能。
この時、識別子がマクロ名として定義されていれば
制御式を1と評価する。そうでない場合は0と評価する。
制御式の評価結果が0以外ならば、
その間にあるソースコードはコンパイル対象となる。
制御式中のマクロ置換は、
(defined演算子のオペランドになるマクロ名を除く)
評価の前に行われる。
この変換で、字句definedが生成される場合の動作は未定義。
#ifdefと#ifndefは、それぞれ
#if defined 識別子、#if !defined 識別子と等価。
条件付き取り込みを入れ子にすることは可能。
プリプロセッサ指令について調べてみました。
・プリプロセッサ指令は、#で始まり、改行文字で終わる。
・#の前に空白類文字があってもよい。
・#から改行までの間にあってもよい空白類文字は空白と水平タブのみ。
・以下の例の2行目はプリプロセッサ指令とはならない。#で始まっていないため。
#define EMPTY
EMPTY #include
・プリプロセッサ指令は、#で始まり、改行文字で終わる。
・#の前に空白類文字があってもよい。
・#から改行までの間にあってもよい空白類文字は空白と水平タブのみ。
・以下の例の2行目はプリプロセッサ指令とはならない。#で始まっていないため。
#define EMPTY
EMPTY #include
関数形式マクロの長所・短所
2010年3月20日 お仕事関数形式マクロの長所・短所について調べてみました。
長所
・どんな型の実引数に対しても動作する。
・インラインコードに展開されるので、関数呼び出しのオーバーヘッドがない。
短所
・実引数の評価回数が複数になることがあり、思わぬ不具合を生むことがある。また、処理速度が遅くなる懸念もある。
・何度も呼び出される場合に、コードサイズが大きくなる。
・アドレスを持たないので、アドレスを得ることができない。
⇒副作用を避けるために、関数自体を括弧で括る。また関数内にある引数も括弧で括る。
⇒コールする時には、副作用に気をつける(展開後のコードを確認する等)。
長所
・どんな型の実引数に対しても動作する。
・インラインコードに展開されるので、関数呼び出しのオーバーヘッドがない。
短所
・実引数の評価回数が複数になることがあり、思わぬ不具合を生むことがある。また、処理速度が遅くなる懸念もある。
・何度も呼び出される場合に、コードサイズが大きくなる。
・アドレスを持たないので、アドレスを得ることができない。
⇒副作用を避けるために、関数自体を括弧で括る。また関数内にある引数も括弧で括る。
⇒コールする時には、副作用に気をつける(展開後のコードを確認する等)。