2012-12-21 14 views
5

次のコードを考えてみましょう:xyyzyのプロトタイプは、使用の時点では未知であるが、プロトタイプを持たない関数のデフォルトの戻り値の型がそうintあるので、これはC89モードで動作し、今c99モードでgccが暗黙の関数宣言を間違って実行していますか?

int main (void) { 
    int i = xyzzy(); 
    return i; 
} 
int xyzzy (void) { 
    return 42; 
} 

を暗黙関数プロトタイプと実際の関数は互換性があります。

そして、あなたはfloatに、関数の戻り値の型を変更した場合(予想通り)実際には、あなたが得る:

testprog.c:6: error: conflicting types for 'xyzzy' 
testprog.c:2: error: previous implicit declaration of 'xyzzy' was here 

暗黙のプロトタイプと実際の機能はもはや一致ので。

C89は 3.7.1 Function definitionsに言って、この持っているので、期待されている
testprog.c: In function 'main': 
testprog.c:2: warning: implicit declaration of function 'xyzzy' 

int型のextern int型の最大値を(、

gcc --std=c89 --pedantic -Wall -Wextraでコンパイルされた元のコードは、私だけに警告を与えますint b){...}:ここではexternはストレージクラス指定子であり、intは型指定子です(それぞれ省略可能な場合もあります)。関数呼び出しに括弧で囲まれた引数リストの前の式は、単に識別子で構成されており、何の宣言は、この識別子のために表示されていない場合は、識別子が暗黙的に宣言されている場合は

3.3.2.2 Function calls

まったく同じように、 を含む最も内側のブロックでは、宣言は extern int identifier();が表示されます。

ので、それを宣言するまでの機能を使用することは間違いなく、デフォルトのプロトタイプで結果が作成される

呼び出される関数を表し、式がオブジェクトを返す関数へのポインタ型を持つ場合:しかし、両方のこれらのフレーズがC99で削除されていると我々は代わりに(私の太字)6.5.2.2 Function callsで見つける


関数呼び出し式は、そのオブジェクト型と同じ型を持ち、6.8.6.4で指定された値を持つ。 それ以外の場合は、関数呼び出しにvoid型があります。

私はあなたが関数を呼び出すしようとすると、それは暗黙的にvoid戻り値の型で宣言されたの視界には宣言がありませんならば、それは、それを意味するように理解しています。

gcc --std=c99 --pedantic -Wall -Wextraでコンパイルすると、暗黙の宣言についても同じ警告が表示されます。

c99は暗黙のうちに関数voidを返すように宣言してはいけませんか?もしそれがあったとすれば、私はを返して再宣言しようとしたときと似たエラーprevious implicit declarationを期待していたでしょう。

ここにgccが壊れていますか、または標準で何かが欠けていますか?

+0

sun/oracle ccコンパイラで-xc99オプションを指定し、funcにfloatを使用すると、current:function(void)returns float; previous:function()戻り値int: "pax.c"、2行目。私はそれが難しいと思う2つの異なるコンパイラは、たとえ不可能ではないにしても、標準の同じ誤解を示しています - 標準は、物事がどうなるかを得るのを難しくする言語を避けるべきです! – ShinTakezou

+0

@Shinは、Sunコンパイラのようにも見えますが、デフォルトではC99モードでも "intを返します"。この場合、私は標準を間違って読んでいる可能性があります。私はちょうどどこにいるのか分からなかった。 – paxdiablo

+1

あなたは正しいとは言えません。後方互換性はありません。 C99では、関数または関数定義の宣言(できればプロトタイプ宣言)をスコープ内に表示することになっています。スコープ内の宣言は診断を必要としません(コンパイルに失敗する可能性があります)。 ISO C90のセクション番号は、C89 ANSI標準から引用しています。 –

答えて

関連する問題