C言語関係掲示板

過去ログ

No.528.暗黙宣言のエラー

[戻る] [ホームページ]
No.4134

暗黙宣言
投稿者---のりすけ(2003/01/03 01:44:28)


今、アセンブラをC言語で翻訳するっていうプログラムを
紙からパソコンに打ち込んでいるのですが、
実行してみると、暗黙宣言されたっていうエラーがたくさん出るんです。
exitやstrcpy、strcmpなどを使うと出ちゃうみたいです。
エラーが出ない良い方法などあるでしょうか?

No.4136

Re:暗黙宣言
投稿者---かずま(2003/01/03 02:43:32)


> 今、アセンブラをC言語で翻訳するっていうプログラムを

C言語で書かれたアセンブラということでしょうか。

> 紙からパソコンに打ち込んでいるのですが、
> 実行してみると、暗黙宣言されたっていうエラーがたくさん出るんです。

コンパイルしてみると、ですよね。
エラーが出たら、そのプログラムは実行できないはずです。
それとも、コンパイラを実行してみると、という意味でしょうか。

> exitやstrcpy、strcmpなどを使うと出ちゃうみたいです。
> エラーが出ない良い方法などあるでしょうか?

本当にエラーですか?
警告(warning)ではありませんか。

エラーが出るソースプログラム(の一部)、およびエラーメッセージをそのまま、
ここに貼り付けていただけると、もっと適切な助言が得られるかもしれません。

No.4140

Re:暗黙宣言
投稿者---のりすけ(2003/01/03 11:33:20)


お返事ありがとうございます。
説明不足で申し訳ありませんでした。
僕はC言語の知識はほとんどないんですが、
C言語で書かれたプログラムでアセンブラの文を実行(翻訳?)できるように
しようというプログラムだと思います。
インタプリタ?でコンパイルしてみると以下のエラーが出ます。
#include <stdio.h>
#include <string.h>
と二つ使ってみると暗黙宣言のエラーが減りました。
どうかよろしくお願いいたします。

行番号 42: 'exit' が暗黙宣言された
行番号 52: 'syntax_tbl' が暗黙宣言された
行番号 96: 'toupper' が暗黙宣言された
行番号 124: 'get_symbol' が暗黙宣言された
行番号 42: 関数 'exit' が未定義

00042 exit(-1);
00052 cnd = syntax_tbl();
00096 *ppt++ = toupper(*pt++);
00124 symbol_no = get_symbol(&sym_pos, in_symbol);

No.4146

Re:暗黙宣言
投稿者---かずま(2003/01/04 01:09:43)


> 行番号 42: 'exit' が暗黙宣言された
> 行番号 52: 'syntax_tbl' が暗黙宣言された
> 行番号 96: 'toupper' が暗黙宣言された
> 行番号 124: 'get_symbol' が暗黙宣言された

exit は <stdlib.h>、toupper は <ctype.h> です。
syntax_tbl と get_symbol は、標準ライブラリの関数ではなく、
おそらくこのプログラムのどこかで定義されているのでしょう。
その定義より前に、それらの関数を参照したから、暗黙宣言とメッセージが
出ているのです。ソースファイルの先頭で、それらの関数を宣言してみてください。
しかし、C は C++ と違って、宣言無しで、関数を呼び出しても、エラーにならない
はずなんですが、ソースファイルの拡張子を .c ではなく、.cpp にしていませんか。


> 行番号 42: 関数 'exit' が未定義

これは変ですね。exit は標準ライブラリですから、未定義にならないはずです。
コンパイラは何ですか。

No.4157

Re:暗黙宣言
投稿者---のりすけ(2003/01/04 23:41:36)


ありがとうございます!!
<stdlib.h> と <ctype.h> を入力したところ、exit と toupper の
エラーがなくなりました。
そして確認したところ、syntax_tbl と get_symbol の宣言がされてませんでした。
そこで非常に恐縮なのですが、なにで宣言したらよいでしょうか??
int や char で宣言したところ「関数呼出しの構文エラー」になってしまいました。
関係ありそうな文を抜粋します。
あと、ソースファイルの拡張子は .c で保存しています。
そしてコンパイラは UltraC というのを使ってます。
項目にインタプリタって書いてあるのが?なんですが。
どこかのネットでもう一つコンパイラを探してみます!

int cnd = 0;
.
.
.
cnd = syntax_tbl();
if(cnd<0)
return cnd;
--------------------
symtbl_cnt = 0;
symtbl_line = 0;
symtbl_culm = 0;
sym_pos = 0;
symbol_no =-1;
stack_pt = 0;
stack[stack_pt]=0;
shift_sw = 0;
loop = 1;
while(loop)
	{ // 1000
	if(shift_sw==0)
		{
		symbol_no = get_symbol(&sym_pos, in_symbol);
		if(symbol_no<0)
			{
			loop = 0;
			continue;
			}
		strcpy(syntax_symbol, in_symbol);
//printf("symbol_no => %d, sym_pos => %d, in_symbol => %s\n", symbol_no, sym_pos, in_symbol);


No.4166

Re:暗黙宣言
投稿者---カンナ(2003/01/05 03:31:15)
http://hana.sakura.ne.jp/~elfin/k/


 インタープリタでインタープリタを動かそうとしているのではないかという気
がふつふつと……それはともかく。

>int cnd = 0;
  :
>cnd = syntax_tbl();

…ということからsyntax_tblは「引数なし、intを返す、関数」のようですね。
宣言は「int syntax_tbl();」です、

>sym_pos = 0;
>symbol_no =-1;
  :
> symbol_no = get_symbol(&sym_pos, in_symbol);
  :
>//printf("symbol_no => %d, sym_pos => %d, in_symbol => %s\n", symbol_no, sym_pos, in_symbol);

…ということはget_symbolは「intへのポインタとcharへのポインタを引数に
とり、intを返す、関数」だと思われます。「int get_symbol(int*, char*);」
がその宣言として適切です。

 かずまさんが書かれているように、実際にはプログラムのどこかでsyntax_tbl
やget_symbolが定義されているはずですから、そこからプロトタイプをコピーし
て宣言とするのが適切です。ソースを検索するなどして探してみてください。


 以下余談。
 本文から推定するに入力されているプログラムは古いC言語で書かれているよ
うですね。今のC言語では関数の宣言と定義でプロトタイプが一致している必要
がありますが(つまり一致していないとコンパイルエラーになりますが)、古い
C言語では宣言には戻り値だけを指定し引数は書きませんでした。例えば標準ラ
イブラリの「sin」と「fopen」の宣言は以下のようになります。

sin
 今のC言語:double sin(double);
 古いC言語:double sin();

fopen
 今のC言語:FILE* fopen(char*, char*);
 古いC言語:FILE* fopen();

 また今のC言語では宣言や定義よりも前にその関数を呼び出そうとするとエラ
ー(コンパイラの設定によっては警告)になります。しかし古いC言語ではその
場合には「intを返す関数」として宣言されているものと暗黙に扱われ、エラー
にはなりませんでした。これが「暗黙宣言」です。従って例えば「get_symbol」
は「int get_symbol();」と暗黙に宣言されているものとして扱われており、
これは本来の宣言と同じものですよね(引数は書きませんし)。

 古いC言語を受け入れてくれるコンパイラもありますが(というか大抵はそう
だと思いますが)、UltraCは学習用ということですからエラーになるのでしょう。
もしかするとUltraCの設定を変えれば古いC言語でも実行してくれるかもしれま
せんので、その辺を調べてみるのもよいかと思います。

No.4167

Re:暗黙宣言
投稿者---かずま(2003/01/05 03:32:56)


> そして確認したところ、syntax_tbl と get_symbol の宣言がされてませんでした。
> そこで非常に恐縮なのですが、なにで宣言したらよいでしょうか??

syntax_tbl の定義があるはずです。それと同じ形で宣言します。
例えば、
int syntax_tbl(void)
{
    ......
}
という関数定義があれば、
cnd = syntax_tbl(); という関数呼び出しより前に書くべき関数宣言は、
int syntax_tbl(void);
です。{ ..... } を ; に変えるだけです。


> int や char で宣言したところ「関数呼出しの構文エラー」になってしまいました。

int syntax_tbl; と宣言したんでしょうか。これでは、
syntax_tbl は関数でなく、変数ということになってしまいますから、
cnd = syntax_tbl() という関数呼び出しが出来ません。

get_symbol のほうは、関数呼び出しからだけでは引数の型がわかりませんが、
おそらく、
int get_symbol(int *, int);
ではないでしょうか。正しい宣言は、関数定義を見てください。
関数定義のところでは、引数の名前がかかれていると思いますが、
関数宣言では、引数の名前は省略できます。

No.4169

Re:暗黙宣言
投稿者---かずま(2003/01/05 03:42:29)


> get_symbol のほうは、関数呼び出しからだけでは引数の型がわかりませんが、
> おそらく、
> int get_symbol(int *, int);
> ではないでしょうか。正しい宣言は、関数定義を見てください。

これは、間違いですね。私は、コメントになっている printf を見落としていたので、
in_symbol の型がわからず、勝手に int にしてしまいました。
カンナさんの説明が正しいと思います。

No.4185

Re:暗黙宣言
投稿者---のりすけ(2003/01/05 23:10:13)


みなさんありがとうございます!!
教えてもらった通り宣言したところエラーがなくなりました。
エラーは古いプログラムの書き方からだったんですね。
これを書いたのは古い先生なので。。

あともうひとつなんですが、
以下のプログラムは他のプログラムの一部?だと思うんですが、
「行番号 13: '!=' の演算項が不当」というエラーが出てしまいます。
(  while(*pt != NULL)    )
どこかおかしいところがありましたら、
どうぞご指摘の方をよろしくお願いいたします。

#include <stdio.h>
int asctoint(char *in_asc, int *out_bin)
{
int cnd = 0, sign = 0, work_bin, tmp;
char *pt;
pt = in_asc;
if(*pt == '-')
	{
	sign = 1;
	pt += 1;
	}
work_bin = 0;
while(*pt != NULL)
	{
	tmp = *pt++ & 017;
	work_bin = work_bin * 10 + tmp;
	}
if(sign)
	work_bin = -work_bin;
*out_bin = work_bin;
return cnd;
}


No.4190

Re:暗黙宣言
投稿者---カンナ(2003/01/05 23:49:32)
http://hana.sakura.ne.jp/~elfin/k/


 NULLは基本的にポインタに対する値です。意図としてはヌル文字と
比較したいのでしょうから、NULLではなく'\0'を使ってください。
 ただたいていのコンパイラでは元のままで問題なくコンパイルされ
ると思います。恐らくはNULLも'\0'も全ビット0の値として実装され
ているためではないでしょうか。

 本題とは関係ありませんが、違う質問をするときには前の質問の返
信で行うのではなく新しくスレッドを起こす方が適切です。

No.4229

Re:暗黙宣言
投稿者---のりすけ(2003/01/07 20:05:46)


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

> 本題とは関係ありませんが、違う質問をするときには前の質問の返
>信で行うのではなく新しくスレッドを起こす方が適切です。

以後気をつけます!