FC2ブログ

プロトタイプ宣言の無い関数2

どっかで書いたよなー、と探したらあった。
プロトタイプ宣言の無い関数

本日出会ったのは、
#include < stdio.h >
...
sprintf(buf, "%s", (char *)getenv("MYENV"));

64bit機で、sprintfSEGV
こいつの問題は以前も書いたように、getenvのプロトタイプ宣言が無いこと。
getenvstdlib.hで宣言されているのにインクルードしていない。
従って、getenvは、
int getenv(void)
とコンパイル単位内では解釈されてしまう。
(この処理系でのintは4Byte、char *は8Byte)
char *(8Byte)がint(4Byte)に切り詰められ、それをchar *(8Byte)にキャストする、というとんでもない話。

ここで(char *)と妙なキャストをしてくれなければ、コンパイラは”型が違うよ”と警告してくれたりするのだけれども、キャストしてくれたおかげで通常のwarningレベルでは素通りしてしまう。

warningレベルを上げることでやっと、
no proto-type ...declarated implicitly...

というようなメッセージが吐かれる。
『プロトタイプ宣言が無いので、暗黙の宣言としちゃうよ』、そのまんまの意味。

件のソースは前後の様子から、stdlib.hをインクルードしていない為に出たエラー/ワーニングに対して内容も見ずに、char *にキャストしてコンパイラを黙らせたような雰囲気。
しかもこれベースになるライブラリ。涙も出やしない。
たまたま落ちてくれたからいいようなものの、うまい具合に落ちなかったりした日にゃ目も当てられない。

こういうのを見ると、C++があれだけキャストに敏感である理由が良くわかる。

###
さらにタチが悪いものに、同様にプロトタイプ宣言が無いままで
long n = atol(str);
ってぇのもある。
これもwarningレベルを上げなければ素通りである。しかもintの範囲の値(負の数含む)しか返さずに平然と動く

### 2006/11/19 追記
暗黙に「intを返す」とされるのはC99では未定義と変更されている。
C99対応コンパイラでは警告を出してくれるものと期待するが...んー(謎
スポンサーサイト



コメントの投稿

非公開コメント

ひさびさに・・・

最近忙しくてなかなか拝見できなかったけど・・・
さっそくこの話題書いてましたねー(^^;

この話題向こうでは騒ぎになってるらしく・・・
見直せとか、いろんな物議をかもし出してるようっす。

そもそも検証もろくにせずGoサインだしてる、いんちき会社が
責任転嫁しそうな雰囲気さえある始末・・・(--;

※ちなみに公共性考えて会社名、個人名はだしません。
でもアッキーって呼び名はOk?(^^;

アッキーはOKでしょー。公共性ないし。
むしろ公共の福祉のためには実名出した方がいいのかも。(^^;オイオイ
プロフィール

f_yamaki

Author:f_yamaki

アクセスカウンタ
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
カテゴリー
ブロとも申請フォーム

この人とブロともになる

ブログ内検索
RSSフィード
リンク