2

I have the following code:

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

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

If I compile with:

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

then I get the expected output:

3.400000

If I try to enable warnings though and target C89, I can't get it to compile:

$ 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]

I found out that fmax() is only defined by the C99 standard, not C89. So the question is: why do these exact same commands work without issuing any warning on a Mac, but not on a Linux machine?

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
rid
  • 61,078
  • 31
  • 152
  • 193

3 Answers3

6

I think you need to build with -std=c99 (see the manual page for fmax).. see this

From fmaxf manual page

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

It seems fmax also requires C99

Krishnabhadra
  • 34,169
  • 30
  • 118
  • 167
  • I didn't downvote. I see I was badly misled by the [`math.h` Wikipedia page](http://en.wikipedia.org/wiki/C_mathematical_functions) stating that "in C89, all functions accept only type double for the floating-point arguments", implying that all functions *are* available in C89, just not the `*f` versions. Editing that page now. But still, the second question stands. Why do I not get any warning on a Mac with the same source and the same `gcc` arguments? – rid Jun 07 '12 at 06:52
  • 1
    It will be very helpful if down voting people left a comment on the reason for down vote.. – Krishnabhadra Jun 07 '12 at 06:55
1

From gcc documentation:

5.44 Other built-in functions provided by GCC

GCC provides a large number of built-in functions other than the ones mentioned above. Some of these are for internal use in the processing of exceptions or variable-length argument lists and will not be documented here because they may change from time to time; we do not recommend general use of these functions.

The remaining functions are provided for optimization purposes.

GCC includes built-in versions of many of the functions in the standard C library. The versions prefixed with _builtin will always be treated as having the same meaning as the C library function even if you specify the -fno-builtin option. (see C Dialect Options) Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function will be emitted.

Outside strict ISO C mode (-ansi, -std=c89 or -std=c99), the functions _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 and yn may be handled as built-in functions. All these functions have corresponding versions prefixed with _builtin, which may be used even in strict C89 mode.

The ISO C99 functions _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 and vsscanf are handled as built-in functions except in strict ISO C90 mode (-ansi or -std=c89).

guido
  • 18,864
  • 6
  • 70
  • 95
  • The second question stands then. Why does `gcc` with the exact same source and exact same parameters not issue any warning on a Mac? – rid Jun 07 '12 at 06:49
  • locate and open you included *math.h*; it should point you to *bin/mathcalls.h*. Inside this, find fmaxf definition and check if it is inside a *#ifdef __USE_ISOC99* – guido Jun 07 '12 at 07:05
  • My Mac's `/usr/include/math.h` doesn't include `bin/mathcalls.h`, but instead it includes a `architecture/i386/math.h`, which doesn't contain any reference to `__USE_ISOC99`. Even so, shouldn't these warnings be generated by `gcc` itself, regardless of what might be available on the system? – rid Jun 07 '12 at 07:10
  • nope it's all if- or ifn- defined or macroed in header files. would you try to find fmax or fmax in your includes and post it in the question? – guido Jun 07 '12 at 07:32
  • All `fmax*()` functions are defined in the architecture `math.h`. But if `gcc` doesn't warn me about using a non-standard function, then what is the purpose of `-std`? What else can I do to be warned about this? – rid Jun 07 '12 at 07:35
  • the purpose of -std is to support some dialect, that is, generally, disabling (or enabling like with -std=gnu99) gnu gcc own extensions and language syntax features (ie oneline comments: // ). It appears to be a bug in the released gcc version for darwin you installed, and you should report it. I think (though not sure of) that gcc is picking up the \_\_builtin\_ function (despite the -ansi) – guido Jun 07 '12 at 07:55
0

It's defined by C99 but not C89.

Search "C99" in man for fmaxf

waitingkuo
  • 89,478
  • 28
  • 112
  • 118