- ベストアンサー
C言語ソースのエラーメッセージを解析しよう
- 熟練者によるC言語ソースのエラーメッセージ解説
- error関数の意図不明な要素について解説
- エラーメッセージを単純にファイル出力する関数
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
va_list 等は、可変長引数を扱うためのものです。 va_list 、 可変長引数 等で検索すると、より詳しい解説がみつかります。 例えば、 printf では、引数が1つのときもあれば、3つのときもあります printf("hello world"); /* 引数が一つ */ printf("No.%d is %f\n",i,d[i]) ; /* 引数が3つ */ こういうのが可変長引数です。 後半のループは、 配列 fmt と変数 k の内容を追い掛ければわかるかと思います。 %があったらmessからfmtにコピーを始めて、 s,d,x等があったら、fmt を書式文字列に指定して、fprintf を実行しています。そのとき、呼び出し元で指定された可変長の引数から順番に取り出して、fprintfに指定しています。 例えば error("aa%2c",'b') ; だったら a → fprintf(f2,"%c",'a') ; /* k==0だから */ a → fprintf(f2,"%c",'a') ; /* k==0だから */ % → fmt ="%" ; /*k=1に */ 2 → fmt ="%2" ; /*k=2に */ c → fmt ="%2c" ; fprintf(f2,"%2c",'b') /*k=0に */ つまりは error(msg, a0, a1, ... ) ; が { fprintf(f2, msg, a0, a1, ...) ; exit(1); } と「ほぼ同等」の意味になります。 ただ。 単純に{ fprintf(f2, msg, a0, a1, ...) ; exit(1); } とするなら、va_list をそのままfprintfに渡せる「 vfprintf 」という関数があります。 わざわざmsgを解析する必要はありません。 fprintf(f2,fmt,(char)va_arg(list,int)); の (char)va_arg(list,int) については、意図をわかりかねます。 Cの可変長引数のルールとして「int以下の整数は、intに変換される」というのがあります。 char c ='a' ; printf("%c",c ) ; とした場合、実際には printf("%c",(int)c ) ; となります。よって、va_argで取り出す際には va_arg(list,int) なのが正解です。 しかし、それをまたcharに戻す理由はわかりません。 fprintfも可変長引数なので fprintf(f2,fmt,(char)va_arg(list,int)); は fprintf(f2,fmt,(int)( (char)va_arg(list,int) ) ); と同義です。 "%c"の方はまだ「charとして扱いたい」という(無意味な)理由が考え付きますが、 "%x","%d"の方はわかりません。 「int i ; error("%d",i) と指定なっていたら、iはintではなくcharとして下位8ビットしか見ない、ということなのでしょうか。
お礼
お返事遅くなり大変失礼しました(PCが不調で再インストールに時間がかかってました) すみません、一か所写経で間違いがあり(古いソースで紙媒体を手打ちしてました) case'd':case'x': fprintf(f2, fmt, va_arg(list,int));でした。 回答を頂いた後半の意図不明としておられた所そのもので、申し訳ありません。 丁寧な解説ありがとうございました。