函数fmax的隐式声明

时间:2012-06-07 06:38:03

标签: c ansi c89

我有以下代码:

#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机器上发出警告?

3 个答案:

答案 0 :(得分:6)

我认为您需要使用-std = c99进行构建(请参阅fmax的手册页)..请参阅this

来自fmaxf manual page

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

似乎 fmax也需要C99

答案 1 :(得分:0)

来自gcc documentation

  

5.44 GCC提供的其他内置功能

     

GCC提供了大量的内置功能   上文提到的。其中一些是供处理内部使用的   例外或可变长度的参数列表,不会   记录在这里,因为它们可能会不时变化;我们不   建议一般使用这些功能。

     

其余功能仅用于优化目的。

     

GCC包含了许多功能的内置版本   标准C库。前缀为_ builtin 的版本将始终使用   被视为具有与C库函数相同的含义   如果指定-fno-builtin选项。 (参见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,    fmax ,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,nearbyintf,nearbyintl,nearbyint,   nextafterf,nextafterl,nextafter,nexttowardf,nexttowardl,   nexttoward,remainderf,remainderl,remainder,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)。

答案 2 :(得分:0)

它由C99定义,但不是C89。

搜索“C99” man for fmaxf