ページ 11

スタティックライブラリでのウォーニング。

Posted: 2007年2月05日(月) 20:08
by 大工
最近ライブラリの作成を勉強している大工です。

スタティックライブラリについての質問です。

コンパイルした結果が・・・

$ gcc -c func2.c
func2.c: In function `msg':
func2.c:5: warning: function returns address of local variable

です。ソースコードは以下です。
#include <stdio.h>

char *msg(){
	char m[/url] = "This is a test.\n";
	return m;
}
このワーニングの解説を宜しくお願いします。

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月05日(月) 20:24
by Hermit
Excite翻訳で翻訳すると、
"機能は局所変数のアドレスを返します。"
となりました。
msg() 中で確保された領域のアドレスですので、
msg を抜けた時点で、その領域は開放され、
他で再利用される可能性大ですので、使わない方が懸命です。

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月05日(月) 20:32
by 大工
#include <stdio.h>

int  mul(int a){
	return a * a;
}
上記のソースでコンパイルした場合質問にあるようなワーニングは出なかったんですが違いは何なんですか?
アドレスを返しているという点なんでしょうか??

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月05日(月) 20:34
by 大工
このコメントは削除して下さい。

返信ミスです

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月05日(月) 20:35
by GPGA
>では下記のソースでコンパイルした場合質問にあるようなワーニングは出なかったんですが違いは何なんですか?
>アドレスを返しているという点なんでしょうか??
はい、その通りです。

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月05日(月) 20:39
by box
> アドレスを返しているという点なんでしょうか??

どうしても配列mのアドレスを返したい場合は、
staticを付けて定義してください。

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月05日(月) 20:42
by 大工
あぁ~なるほど!!
開放されるんですね・・・・・

ありがとうございます

static ですか・・・今思えばそうですよね・・^^;

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月06日(火) 00:39
by 大工
すみません・・・

実際コンパイルしてみたらまたワーニングが・・・・
#include <stdio.h>

char * _msg(){
	static char _m[/url] = "This is an apple.";
	return _m;
}
#include <stdio.h>

char * msg(){
	static char m[/url] = "This is a test.\n";
	return m;
}
#include <stdio.h>

int main (void){

	char *p, *q;

	p = msg();
	q = _msg();

	printf("p: %sq: %s\n", p, q);

	return 0;
}
上から func1.c func2.c compe.c です。

cygwinでコンパイルしてみたところ
$ gcc compe.c text.lib -o file
compe.c: In function `main':
compe.c:7: warning: assignment makes pointer from integer without a cast
compe.c:8: warning: assignment makes pointer from integer without a cast
と表示されてしまいました。

func1.c func2.c compe.c を1つにまとめたtest.c をコンパイルするとワーニングもでず成功しました。

原因を教えて下さい。

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月06日(火) 04:17
by 大工
extern char * _msg();
extern char * msg();

とプロトタイプ宣言をcompe.cにすればコンパイルできました。

別の場所で聞いてみてこの方法を教えてくれたんですが、『なぜ』という部分は教えて頂けませんでした。


どうしてプロトタイプ宣言が必要なんでしょうか?

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月06日(火) 09:36
by box
> compe.c:7: warning: assignment makes pointer from integer without a cast
> compe.c:8: warning: assignment makes pointer from integer without a cast

compe.cにmsg()と_msg()のプロトタイプ宣言がない場合、
コンパイラはmsg()と_msg()の戻り値をint型とみなします。

msg()の戻り値をpに、_msg()の戻り値をqにそれぞれ代入する際、
int型をchar *型に代入しようとすることになります。
そこで、コンパイラは「左右両辺の型が異なる代入を行なおうとしていますが、
大丈夫ですか?」という意味の警告を出します。

Re:スタティックライブラリでのワーニング。

Posted: 2007年2月06日(火) 10:33
by 大工
戻り値がint型ですか・・・・

まったく知りませんでした・・・

ありがとうございました。