2

次のコードがあります。

#include <stdio.h>
#include <math.h>

int main(void) {
    printf("%f\n", fmax(1.2, 3.4));
    return 0;
}

私がコンパイルした場合:

gcc a.c -o a && ./a

次に、期待される出力を取得します。

3.400000

ただし、警告を有効にして C89 をターゲットにしようとすると、コンパイルできません。

$ gcc -Wall -Wextra -std=c89 -pedantic -Wstrict-prototypes a.c -o a
a.c: In function ‘main’:
a.c:5:5: warning: implicit declaration of function ‘fmax’ [-Wimplicit-function-declaration]
a.c:5:5: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat]
/tmp/cc8d2iQl.o: In function `main':
a.c:(.text+0x1d): undefined reference to `fmax'
collect2: ld returned 1 exit status
$ gcc -Wall -Wextra -std=c89 -pedantic -Wstrict-prototypes a.c -lm -o a
a.c: In function ‘main’:
a.c:5:5: warning: implicit declaration of function ‘fmax’ [-Wimplicit-function-declaration]
a.c:5:5: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat]

fmax()C89ではなく、C99標準でのみ定義されていることがわかりました。問題は、これらのまったく同じコマンドが、Mac では警告を出さずに機能するのに、Linux マシンでは機能しないのはなぜでしょうか?

4

3 に答える 3

6

-std=c99 でビルドする必要があると思います (fmax のマニュアル ページを参照してください)。これを参照してください。

fmaxfマニュアルページより

fmax(), fmaxf(), fmaxl():
_XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L;
or cc -std=c99

fmax にも C99 が必要なようです

于 2012-06-07T06:43:53.817 に答える
1

gccドキュメントから:

5.44 GCC が提供するその他の組み込み関数

GCC には、上記以外にも多数の組み込み関数が用意されています。これらのいくつかは、例外または可変長の引数リストの処理で内部使用するためのものであり、時々変更される可能性があるため、ここでは説明しません。これらの機能を一般的に使用することはお勧めしません。

残りの関数は、最適化のために提供されています。

GCC には、標準 C ライブラリの多くの関数の組み込みバージョンが含まれています。-fno- builtinオプションを指定しても、_builtin を前に付けたバージョンは、常に C ライブラリ関数と同じ意味を持つものとして扱われます。(C 方言オプションを参照してください) これらの関数の多くは、特定の場合にのみ最適化されます。特定のケースで最適化されていない場合、ライブラリ関数への呼び出しが発行されます。

厳密な ISO C モード (-ansi、-std=c89 または -std=c99) の外では、関数 _exit、alloca、bcmp、bzero、dcgettext、dgettext、dremf、dreml、drem、exp10f、exp10l、exp10、ffsll、ffsl、 ffs、fprintf_unlocked、fputs_unlocked、gammaf、gammal、ガンマ、gettext、index、isascii、j0f、j0l、j0、j1f、j1l、j1、jnf、jnl、jn、mempcpy、pow10f、pow10l、pow10、printf_unlocked、rindex、scalbf、 scalbl, scalb, signbit, signbitf, signbitl, significandf, significandl, significand, sincosf, sincosl, sincos, stpcpy, strdup, strfmon, toascii, y0f, y0l, y0, y1f, y1l, y1, ynf, ynl, yn が扱える組み込み関数として。これらすべての関数には、厳密な C89 モードでも使用できる_ builtinで始まる対応するバージョンがあります。

ISO C99 関数 _Exit, acoshf, acoshl, acosh, asinhf, asinhl, asinh, atanhf, atanhl, atanh, cabsf, cabsl, cabs, cacosf, cacoshf, cacoshl, cacosh, cacosl, cacos, cargf, cargl, carg, casinf, casinhf, casinhl, casinh, casinl, casin, catanf, catanhf, catanhl, catanh, catanl, catan, cbrtf, cbrtl, cbrt, ccosf, ccoshf, ccoshl, ccosh, ccosl, ccos, cexpf, cexpl, cexp, cimagf, cimagl, cimag、conjf、conjl、conj、copysignf、copysignl、copysign、cpowf、cpowl、cpow、cprojf、cprojl、cproj、crealf、creall、creal、csinf、csinhf、csinhl、csinh、csinl、csin、csqrtf、csqrtl、csqrt、 ctanf、ctanhf、ctanhl、ctanh、ctanl、ctan、erfcf、erfcl、erfc、erff、erfl、erf、exp2f、exp2l、exp2、expm1f、expm1l、expm1、fdimf、fdiml、fdim、fmaf、fmal、fmaxf、fmaxl、 fmax, fma, fminf, fminl, fmin, hypotf, hypotl, hypot, ilogbf, ilogbl, ilogb, imaxabs, isblank, iswblank, lgammaf, lgamal, lgamma, llabs, llrintf, llrintl, llrint, llroundf, llroundl, llround, log1pf, log1pl 、log1p、log2f、log2l、log2、logbf、logbl、logb、lrintf、lrintl、lrint、lroundf、lroundl、lround、nearintf、nearintl、nearint、nextafterf、nextafterl、nextafter、nexttowardf、nexttowardl、nexttoward、残りf、残りl、残り, remquof, remquol, remquo, rintf, rintl, rint, roundf, roundl, round, scalblnf, scalblnl, scalbln, scalbnf, scalbnl, scalbn, snprintf, tgammaf, tgammal, tgamma, truncf, truncl, trunc, vfscanf, vscanf, vsnprintf vsscanf は、厳密な ISO C90 モード (-ansi または -std=c89) を除き、組み込み関数として扱われます。

于 2012-06-07T06:47:19.537 に答える
0

C99 で定義されていますが、C89 では定義されていません。

fmaxfの man で「C99」を検索 します。

于 2012-06-07T06:47:31.773 に答える