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()仅由 C99 标准定义,而不是 C89。所以问题是:为什么这些完全相同的命令可以在 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, gamma, 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作为内置函数。所有这些函数都有相应的版本前缀_builtin,即使在严格的 C89 模式下也可以使用。

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, 最大, fma, fminf, fminl, fmin, hypotf, hypotl, hypot, ilogbf, ilogbl, ilogb, imaxabs, isblank, iswblank, lgammaf, lgammal, lgamma, llabs, llrintf, llrintl, llrint, llroundf, llroundl, llround, log1pf, log1pl ,log1p,log2f,log2l,log2,logbf,logbl,logb,lrintf,lrintl,lrint,lroundf,lroundl,lround,nearthintf,nearthintl,nearthint,nextafterf,nextafterl,nextafter,nexttowardf,nexttowardl,nexttoward,residualf,remainderl,residual , 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。

在 man 中搜索“C99”以 查找 fmaxf

于 2012-06-07T06:47:31.773 回答