2016-10-16 15 views
1

問題空間から警告:ポインタを整数

こんにちはGuysは、

はなぜ以下のコンパイルエラーを与えるプロトタイプ機能 char *zalloc();のコメントでしょうか?

プロトタイプ関数のコメントが削除されると、すべてうまく動作しているようです。

例コード:

#include <stdio.h> 

#define ALLOCSIZE 10000 

static char allocbuf[ALLOCSIZE]; 
static char *allocp = allocbuf; // allocbuf = &allocbuf[0] 

char *fn(); 
// char *zalloc(); 

int main() 
{ 
    int a = 100; 

    char *c = fn(); 
    char *d = zalloc(1000000); 

    printf("%s\n", c); 
    printf("%p\n", d); 
} 

char *zalloc(int n) 
{ 
    if (allocbuf + ALLOCSIZE - allocp >= n) { 
     allocp += n; 
     return allocp - n; 
    } else 
     return 0; 
} 

void afree(char *p) 
{ 
    if (p >= allocbuf && p < allocbuf + ALLOCSIZE) 
     allocp = p; 
} 

char *fn() 
{ 
    return "foo"; 
} 

コンパイラエラー:

example_24.c: In function 'main': 
example_24.c:16:12: warning: initialization makes pointer from integer without a cast 
    char *d = zalloc(1000000); 
      ^
example_24.c: At top level: 
example_24.c:22:7: error: conflicting types for 'zalloc' 
char *zalloc(int n) 
    ^
example_24.c:16:12: note: previous implicit declaration of 'zalloc' was here 
    char *d = zalloc(1000000); 
+1

最近のCでは、分かりにくいメッセージは全く異なるはずです:宣言されていない関数 'zalloc'を呼び出してください。宣言されていない関数の呼び出しはCでは不正です。あなたのコンパイラは、言語仕様の要件に正式に従うように設定されていません。 – AnT

+0

@alk申し訳ありません、私の悪い、私はちょっと新しい 'c'なので、ポインタを返す' char * zalloc(int n) 'は'関数ポインタ 'でした。 )、 '関数ポインタ'は関数を指すポインタのようです。 =) – dud3

答えて

2

Cコンパイラは、それが知らない機能を検出した場合、それはintを返すために、それを前提としています。あなたはコンパイラが前に見たことのない機能を呼び出している。このラインで... makes pointer from integer ...

2
char *d = zalloc(1000000); 

zalloc()の結果

が問題になっているメッセージが表示されますchar*を初期化するために使用されています。その場合、コンパイラは、前にint zalloc(int);を行ったかのように、関数がintを返すとみなします。

コンパイラが実際の関数定義を見ているときに、後で整数と "競合する型"エラーでポインタ(char *d)を初期化する警告が表示されます。

0

コンパイラは自動的に 'function-prototyped'ではない関数がintを返すと仮定してコンパイルしません。

さらに、プロトタイプを機能させることをお勧めします。

+0

"*プロトタイプを機能させるのは良い習慣と考えられます。*"なぜですか? :-) – alk

+0

いいえ、コンパイラは宣言されていない関数についてのみ仮定します。プロトタイプは必要ありません。 – melpomene

+0

@Nergal、@alk愚かな質問ですが、 'zalloc()'の 'char'は関数が返すものを教えてくれませんか?もしそうなら、 'zalloc()'から 'return 0 'をどうすればいいですか?0はポインタにとって特別な意味を持っているからでしょうか? – dud3

1

C言語では、関数を呼び出す前に関数を宣言する必要があります(プロトタイプは必要ありませんが、少なくともプロトタイプ宣言はありません)。これは、関数宣言をコメントアウトしたときにプログラムが無効になったことを意味します。

コンパイラの診断メッセージは、主な問題を詳しく見ていないため、誤解を招きます。私はあなたのコンパイラが現代のC仕様の要件に従うように正しく構成されていないと思います。

P.S.注意、BTW、元の関数宣言の両方が非プロトタイプです。パラメータなし関数(fnを参照)のプロトタイプ宣言を作成するには、関数パラメータリストとして明示的に(void)が必要です。

+0

確かに、私はgnu/linux(通常私が使用している)に切り替えて、 'gcc -Wall source.c -o out'を実行して、ウィンドウズcmdでgccを試していました。 'main()'の後に関数が宣言されていてコンパイルして動作していれば、関数の警告を出力します。 – dud3

+0

@ dud3:それはあなたのGCCのバージョンがC89/90に基づくC言語の方言を使用しているか、より現代的なC言語の方言で暗黙の宣言を許していることを意味します。GCCをCプログラミングで使用したいのであれば、 std = ... 'オプション(' -std = c11'など)と '-pedantic-errors'オプションをコマンドラインに追加します。 – AnT

関連する問題