0

man gcc(1) says: the option -ffast-math causes the preprocessor macro __FAST_MATH__ to be defined. Is there any further documentation of that macro?

I would expect that code like

#define __FAST_MATH__ blabla
y = pow(x,a);
#undef __FAST_MATH__

allows control of math optimization, fine grained down to single statements.

However, my tests rather indicate that

#define __FAST_MATH__
#define __FAST_MATH__ on

are all ignored, regardless where they are placed.

[EDIT] They are ignored even if they are placed before

#include <math.h>

"Ignored" means: have no measurable effect. Whereas -ffast-math accelerates my test code by a factor of 3.

Joachim W
  • 7,290
  • 5
  • 31
  • 59
  • If you use `-ffast-math`, then `__FAST_MATH__` is defined. That's probably all there is to it and it has no further effect. – melpomene Mar 31 '17 at 12:27
  • I would guess that the header math.h contains some #ifdef __FAST_MATH somewhere? Also, I would still think that something internal to the compiler behaves differently with -ffast-math. – Uli Schlachter Mar 31 '17 at 12:35
  • The answer http://stackoverflow.com/questions/7420665/what-does-gccs-ffast-math-actually-do has a lot of information on what the flag actually does. – Salix alba Mar 31 '17 at 16:11
  • @Uli: Indeed, ``#ifdef __FAST_MATH__`` appears in math.h, in x86_64-linux-gnu/bits/mathinline.h, and in more locations. It also appears in independent projects like Eigen3 or boost/math. – Joachim W Mar 31 '17 at 16:13
  • @Salixalba: My question was not about what the flag does. My question was: can one achieve the same effect in a more fine-grained way by using the preprocessor macro *instead of* the flag.... And the answer seems to be very simple: No, one cannot. – Joachim W Mar 31 '17 at 16:16
  • 1
    If its fine-grained control you are after you might be able to explicitly call specific library functions. For example, the [fdlibm](http://www.netlib.org/fdlibm/readme) library has a number of different entry points for specific implementations of each maths functions. It has SVID, X/OPEN, or POSIX/ANSI version of the different functions. You are likely to loose portability though. – Salix alba Mar 31 '17 at 19:55

2 Answers2

3

-ffast-math causes the preprocessor macro __FAST_MATH__ to be defined.

It's just a feature-test macro, i.e. you can use conditional compilation depending on whether you specified -ffast-math or not:

#if defined (__FAST_MATH__)
/* Code to use with -ffast-math. */
#else
/* Code to use with -fno-fast-math. */
#endif /* -ffast-math ? */

In most cases, you won't need conditional compilation, but if you need it, you have a macro handy and don't need to define it in your code or per -D on the command line.

Moreover, some (system) headers might depend on it and use faster code provided -ffast-math is on.

More common such macros are __OPTIMIZE__ and __OPTIMIZE_SIZE__. The former is defined if optimization is on (-Og, -O1, -O2, -Os, ...), the latter when optimizing for size is on per -Os.

Note: Making use of such options in the standard library would only work as expected when -ffast-math was introduced as a multilib option, so that specifying it would link different incarnations of libc, libm, libstdc++, etc. like with -m32 / -m64. You can display the multilib layout with gcc -print-multi-lib which yields on my x86_64:

.;
32;@m32

This means we have 2 variants, a default one and one picked with -m32.

emacs drives me nuts
  • 2,785
  • 13
  • 23
1

I believe that you have it backwards. The macro is defined in order for the standard library to use different implementations of the math functions.

Defining it yourself has no effect and might actually be dangerously buggy because the program would be using those alternate implementations when the compiler is not generating the expected code.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • Using `__FAST_MATH__` in the standard library wouln't work as expected, because you'll need `-ffast-math` as multilib option, i.e. you need 2 different variants (or even more if there are more multilib variants like for 32-bit, 64-bit etc.) of the libraries which would be selected by `-f[no-]fast-math`, respectively. Use `gcc -print-multi-lib` to show the multilib layout. `-ffast-math` (would be encoded as `@fast-math)` is not mentioned. – emacs drives me nuts Feb 13 '20 at 16:00