2009-11-23 17 views
8

私は、次のCコードを持っている:なぜgccは「ラウンド関数」の暗黙の宣言を報告しますか?

#include <math.h> 

int main(int argc, char ** argv) 
{ 
    double mydouble = 100.0; 
    double whatever = round(mydouble); 

    return (int) whatever; 
} 

私はこれをコンパイルすると、私は警告を取得:

round_test.c: In function ‘main’: 
round_test.c:6: warning: implicit declaration of function ‘round’ 
round_test.c:6: warning: incompatible implicit declaration of built-in function ‘round’ 

私はCとさびたんだけど、私はの#includeが宣言を持っていると考えをround()をスコープに追加します。私はround()関数がmath.hヘッダーに存在することを確認する私のANSI標準(C99は私が持っている唯一のコピーです)をチェックしました。私はここで何が欠けていますか?

編集:コンパイラはUbuntu(intrepid、IIRC)のGCC 4.3.2です。 gcc -Eを実行すると次のようになります。

$ gcc -E round_test.c | grep round 
# 1 "round_test.c" 
# 1 "round_test.c" 
# 2 "round_test.c" 2 
    double whatever = round(mydouble); 

したがって、定義が明らかにヘッダーに見つかりません。

答えて

17

gccを使用しています。

デフォルトでは、gccはC89と同様の標準を使用します。あなたはそれが(それが準拠する部品)

gcc -std=c99 -pedantic ... 

引用デフォルトでGCC Manual

からC99標準を使用するように「強制」したい場合があり、GCCは、その上のC言語にいくつかの の拡張機能を提供します まれな場合がC 標準と競合します。 C 言語ファミリへの拡張を参照してください。上記の-std オプションを使用すると、 これらの拡張機能が無効になり、C標準バージョンが選択された が矛盾します。 また、C言語の拡張 バージョン明示的 -std = gnu89と(C89用GNUと 拡張)または-std = gnu99(GNU拡張子を持つC99 用)を選択することができます。 C言語の方言オプションが指定されていない場合のデフォルト値は です。-std = gnu89です。 C99のサポートが完了すると、 が将来のリリースで-std = gnu99に変更されます( )。 C99 標準の一部である一部の 機能は、 C89モードの内線番号として受け入れられます。

+1

ありがとうございます、-std = c99はそれを解決するようです。私はround()がC99の追加であることを認識していませんでした(もちろん、私の参考文献はすべてC99であり、これを無視しています)。 –

+0

(驚いています)本当にC99を追加しましたか? –

+0

そうです、C89は 'round()'関数を記述しませんでした(もちろん、コンパイラはそれを拡張子として提供することができます)。 – pmg

3

gccのインストール、システムヘッダー、またはコンパイルオプションに何か問題があります。

-Eでコンパイルしてみてください。これは、どのヘッダがインクルードされているのか、インクルードされているのかを含むプリプロセッサの出力を表示します。私のUbuntu Linuxのシステム上では、この出力を含め約1000行、です:

extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__)); 
+0

私はUbuntu 9.10(Karmic)です。ここで '#include 'は、宣言を含む/usr/include/bits/mathcalls.hをロードする/usr/include/math.hをロードします。 –

0

あなたが入力したコードは、GCC 4.0.1とMacOS Xの10.5.8にきれいにコンパイルされます。オプション '-Wall -Wextra'を指定すると、未使用の引数argcとargvが返されます。

あなたのマシンで<math.h>を見ましたか?

'-stc = c99'などのオプションを試しましたか?

3

あなたはC99をしたいのgccを伝える必要があり、あなたがたlibmにリンクすること:

gcc -std=c99 -lm round_test.c 
-2

あなたは数学ライブラリとリンクする必要があります。したがって、コンパイルするときには、必ず-lmフラグを追加してください。

+1

入力していただきありがとうございますが、これはリンクの問題ではなく、コンパイルの問題です。私は私のコンパイラコマンド(私の悪い)を除外したことに気付きましたが、私はgcc -cでコンパイルしていました。 –

0

C99が答えでしたが、完全な話はちょっと複雑です。私がこれをやってきたのは、Windows用に書かれたライブラリをコンパイルしようとしていたことです。これはround()の独自の「最適化された」定義を持っていました。私はその定義がビルトインと矛盾していると私に言っているリンカのエラーを得たので、定義(および宣言)を削除しました。私がやってしまえば、私は "暗黙の宣言エラー"を得るようになった。

デフォルトのコンパイルモード(-std = c99フラグなし)はC89もC99も準拠していないようです:C89に準拠していれば、競合することなくround()のカスタム定義を提供できるはずです。 C99に準拠していれば宣言はmath.hになければなりません。

+1

デフォルトモードは '-std = gnu89'です:) – pmg

関連する問題