bug.i ------ # 1 "bug.c" # 1 "<built-in>" # 1 "<command line>" # 1 "bug.c" int main () { float f = 1.0; if(isinf(f)) return 1 ; return 0; } ------ Command that does NOT trigger bug gcc bug.c Output of gcc when bug NOT triggered Undefined first referenced symbol in file isinf bug.o ld: fatal: Symbol referencing errors. No output written to a.out collect2: ld returned 1 exit status Command that triggers bug gcc -O bug.c Output of gcc when bug IS triggered (None)
isinf is a standard function, its invocation is simply optimized away at -O.
This function is not present in Solaris9 (although it is indeed available in Solaris10). So - with or without the optimiser - the compile should always fail; unless, of course,the optimiser makes assumptions about the internals of this (but not other) non-existnt functions.
> This function is not present in Solaris9 (although it is indeed available in > Solaris10). So - with or without the optimiser - the compile should always > fail; unless, of course,the optimiser makes assumptions about the internals of > this (but not other) non-existnt functions. The latter of course, since the function is a standard function.
Sorry, I must ask you to help me here. The function [macro] isinf() is not declared [or defined] in any of the Solaris9 include files (the nearest it comes is in /usr/include/ieefp.h, which defines the function finite(), usually one of the same family as isinf()). Nor is it defined [declared] in any of the include files created during the gcc build/install process. Presumably this is why the specimen code isinf() will not compile under gcc3.3.2 with either 'gcc' or 'gcc -O[23]'. Yet such code DOES compile with gcc -O under gcc4.0.2. However, the following does not compile, with or without -O :- int something(float f) { f = f*f ; } int main () { float f ; if(isinf(f)) return 1 ; else return 2 ; return 0; } Here, the optimiser is obviously unable to make assumptions about the value that would be returned by isinf() if the function were present, and the code is rejected. This 'bug' breaks autoconf tests for the presence of isinf()
Again this is a bug in your code/Semi in solaris and not in GCC. isinf is a standard function (it does not have to be implemented as a macro).
> Yet such code DOES compile with gcc -O under gcc4.0.2. However, the following > does not compile, with or without -O :- > > int something(float f) > { > f = f*f ; > } > int main () > { > float f ; > > if(isinf(f)) > return 1 ; > else > return 2 ; > return 0; > } > > Here, the optimiser is obviously unable to make assumptions about the value > that would be returned by isinf() if the function were present, and the code > is rejected. > > This 'bug' breaks autoconf tests for the presence of isinf() Then autoconf should be more clever, for example by compiling w/o optimization or by using a robust test or by passing -fno-builtin to the compiler.
Please forgive my persistence, but :- > Again this is a bug in your code/Semi in solaris and not in GCC. Possibly in Solaris (non-compliance with standard), but the code I have supplied contains no bugs : the code should simply not compile on a system which fails to mention isinf() in its header files and does not provide it in its libraries. > isinf is a standard function (it does not have to be implemented as a macro). As far as I can make out, the C standards require isinf() to be defined as a macro (see http://www.opengroup.org/onlinepubs/009695399/basedefs/math.h.html). But I don't think that's the point at issue. If it IS implemented as a function, then it seems to me that if it (or any other standard function) is not available in the standard libraries at compile time, then compilation should fail, regardless of the level of optimisation and regardless of the context in which the function call appears in the code. The (bug-free) code I have provided shows that success or failure of compilation with optimisation (under 4.0.2 but not 3.3.2) depends on the context in which isinf() is called. > Then autoconf should be more clever, for example by compiling w/o optimization > or by using a robust test or by passing -fno-builtin to the compiler. Yes of course these suggestions would work fine, but they would be in the nature of workarounds. I was merely trying to illustrate that others also seem to believe that the absence of a definition (macro or function) and/or the absence of the function itself should cause a compile-time error.
Well first when using optimization, GCC finds that 1.0 is finite. Your test should look more like: float f = 1.0; int main () { if(isinf(f)) return 1 ; return 0; } But watch out for real optimizing (IPO based ones) compilers for this case.
> Yes of course these suggestions would work fine, but they would be in the > nature of workarounds. I was merely trying to illustrate that others also seem > to believe that the absence of a definition (macro or function) and/or the > absence of the function itself should cause a compile-time error. In a freestanding environment (see the entry for -ffreestanding in the manual) but certainly not in the default gnu89 mode.
OK, I think I have achieved enlightenment. Thank you both for your patience.