可変引数関数
C/C++セキュアコーディングを読んでのメモ.
前から気になってたけど, ちょうど良い機会なので調べてみる(というか本のサンプルをちょっと改変).
#include
- 可変リストの引数に対しては型検査は行われない
- 省略記号は, 引数リストの最後の要素でなければならない(1つ以上の固定パラメータは, 省略記号の前に記載する)
- 可変引数リストの終端は, プログラマと関数の利用者との間の決め事による
省略記号は, 「...」で表される.
サンプルにこんなの組んでみた.
単純な足し算プログラム.
#include<stdio.h> #include<stdarg.h> int sum( int first, ... ); int main( int argc, char *argv[] ) { int n1 = 5; int n2 = 10; int n3 = 15; int n4 = 20; int n5 = 95; printf( "%d + %d = %d\n", n1, n2, sum( n1, n2, -1 ) ); printf( "%d + %d + %d = %d\n", n1, n2, n3, sum( n1, n2, n3, -1 ) ); printf( "%d + %d + %d + %d = %d\n", n1, n2, n3, n4, sum( n1, n2, n3, n4, -1 ) ); printf( "%d + %d + %d + %d + %d = %d\n", n1, n2, n3, n4, n5, sum( n1, n2, n3, n4, n5, -1 ) ); return 0; } int sum( int first, ... ) { int num = 0; int sum = 0; va_list mark; /* 固定引数firstは, va_start()が最初の可変引数の位置を知るために使用 */ va_start( mark, first ); while( num != -1 ){ sum += num; /* va_arg()マクロは, 引数に指定された型のサイズに基いて引数ポインタを進める */ num = va_arg( mark, int ); } /* 後始末 */ va_end( mark ); return sum; }
関数sumの引数の最後を「-1」にしなかったら, セグメントエラーが出て終了する.
実行結果.
[khiker@khlin001 ~/<1>c/secure]$ gcc -Wall test_stdarg.c -o test_stdarg [khiker@khlin001 ~/<1>c/secure]$ ./test_stdarg 5 + 10 = 10 5 + 10 + 15 = 25 5 + 10 + 15 + 20 = 45 5 + 10 + 15 + 20 + 95 = 140
今回は, 引数に取るのをintだけにしたから簡単だったけど, printfみたいなのだったら大変なんだろうなあと思う.