C99 は、配列のサイズに変数を使うことができる。
こんな感じ。
test1.c
void test1( int n )
{
int fixed_array[10];
int varlen_array[n];
printf( "sizeof(fixed_array)==%ld\n", sizeof(fixed_array) );
printf( "sizeof(varlen_array)==%ld\n", sizeof(varlen_array) );
}
test1(10);
と、引数 10 で呼ぶと、
sizeof(fixed_array)==40
sizeof(varlen_array)==40
となる。
しかし、普通の配列とは違ってコンパイル時には sizeof
の値が確定しないので
test2.c
void test2( int n )
{
int fixed_array[10];
int varlen_array[n];
// sizeof(fixed_array) は enum の値に使える
enum{ FIXED_ARRAY_SIZE=sizeof(fixed_array) };
// sizeof(varlen_array) は enum の値に使えないのでコンパイルエラー
enum{ VARLEN_ARRAY_SIZE=sizeof(varlen_array) };
}
enum
の値や case ラベルには使えない。
それと。
test3.c
#define COUNT_OF(x) (sizeof(x)/sizeof(*(x)))
void test3( int n )
{
int varlen_array[some_func(n)];
for( size_t ix=0 ; ix<COUNT_OF(varlen_array) ; ++ix ){
do_something( varlen_array, ix );
}
}
のようなケースで、コンパイラが気づいてくれないと、COUNT_OF マクロ内の除算をループの数だけ実行してしまってもったいない。