strdup関数入りをコンパイル
ところで、strdup関数は多くの処理系で用意されており事実上の標準関数といっていいがANSI C標準ではない。
なので、例えば、
$ bison -dy parser.y $ flex lexer.l $ gcc -std=c89 -pedantic -Wall -Wextra -c lex.yy.c lexer.l: In function 'yylex': lexer.l:12:1: warning: implicit declaration of function 'strdup' [-Wimplicit-function-declaration] lexer.l:12:10: warning: assignment makes pointer from integer without a cast [enabled by default] lex.yy.c: In function 'yy_init_buffer': lex.yy.c:1331:9: warning: implicit declaration of function 'fileno' [-Wimplicit-function-declaration] lexer.l: At top level: lex.yy.c:1083:17: warning: 'yyunput' defined but not used [-Wunused-function] lex.yy.c:1124:16: warning: 'input' defined but not used [-Wunused-function]
のような警告を受ける。
lexer.lには書いていないlex.yy.c中のコードへの警告の責任は自動生成したflexにあるので置いておく。
lexer.l名義に対する警告はstrdupがANSI Cに含まれていないために起こっている。
これはC89だけでなく
$ gcc -std=c99 -pedantic -Wall -Wextra -c lex.yy.c
のようにC99規格を厳格適用しても警告される。
警告は、strdupがlexer.l中で使う時に初めて現れた、それ以前に定義されていない関数であることによる一つ、
それにより暗黙的にint型を返す関数としてコンパイルを進められたが、
yylvalへの代入段階でint値をキャストなしでポインタ型に代入していることによる一つ、計二つである。
標準関数としてのstrdupはヘッダファイルstring.hにそのプロトタイプが書かれているのだが、
ANSI Cを厳格適用するとそのプロトタイプは無かったことにされるのでこうした警告につながる。
標準関数ではあるのでlibcにオブジェクトが存在しており、
$ ar t /usr/lib/libc.a | grep strdup.o strdup.o
コンパイル時の警告を気にしなければリンクは問題ないし実際に動作する。
ちなみに、lex.yy.c名義に対するfileno関数の警告も同様である。
もちろん-std=c89等を付けてANSI C準拠をソースに厳格に求めていることが原因であり、
ANSI Cに準拠することを求めている以上、準拠していない関数が使われているソースは警告されて当然である。
警告が出た場合、このことが原因であって準拠していないことが問題ないと判断できれば、
そのソースをコンパイルするときにはこうしたオプションを与えないか警告を無視するか抑制する、という流れが正しい道だと思う。
ただし、使用環境でint型とポインタ型のサイズ等に不整合がなければの話だが。
不整合がありうるのなら、
lexer.l
...snip #include <string.h> #ifdef __STRICT_ANSI__ char *strdup(const char *); int fileno(FILE *); #endif %} ...snip
などと無理矢理に関数プロトタイプを定義してやれば、
$ gcc -std=c89 -pedantic -Wall -Wextra -c lex.yy.c lex.yy.c:1088:17: warning: 'yyunput' defined but not used [-Wunused-function] lex.yy.c:1129:16: warning: 'input' defined but not used [-Wunused-function]
のように、この件とは無関係の未使用関数の警告のみにすることができる。
もちろん、-std=c89を与えなければgccは__STRICT_ANSI__マクロを定義せず、
string.hの方の関数プロトタイプが与えられて、自前のプロトタイプは使われないので問題ない。
まあ、環境に合わせて正しい道を選択するべきだろう。