如何使用gcc预处理器宏\uuuu FAST\u MATH\uuuuuuu?

如何使用gcc预处理器宏\uuuu FAST\u MATH\uuuuuuu?,math,gcc,optimization,c-preprocessor,Math,Gcc,Optimization,C Preprocessor,man gcc(1)说:选项-ffast math会导致预处理器宏_快速数学_待定义。是否有该宏的进一步文档 我希望代码是这样的 #define __FAST_MATH__ blabla y = pow(x,a); #undef __FAST_MATH__ 允许控制数学优化,细化到单个语句 然而,我的测试表明 #define __FAST_MATH__ #define __FAST_MATH__ on 无论它们放置在何处,都会被忽略 [编辑]即使它们放在前面,也会

man gcc(1)说:选项-ffast math会导致预处理器宏_快速数学_待定义。是否有该宏的进一步文档

我希望代码是这样的

#define __FAST_MATH__ blabla
y = pow(x,a);
#undef __FAST_MATH__
允许控制数学优化,细化到单个语句

然而,我的测试表明

#define __FAST_MATH__
#define __FAST_MATH__ on
无论它们放置在何处,都会被忽略

[编辑]即使它们放在前面,也会被忽略

#包括

“忽略”是指:没有可测量的影响。而-ffast math将我的测试代码的速度提高了3倍。

我相信你的测试代码是反向的。定义宏是为了让标准库使用不同的数学函数实现


自己定义它没有任何效果,实际上可能会有危险的错误,因为当编译器没有生成预期的代码时,程序将使用这些替代实现。

我相信您的定义是反向的。定义宏是为了让标准库使用不同的数学函数实现

自己定义它没有任何效果,而且实际上可能存在危险的错误,因为当编译器没有生成预期代码时,程序将使用这些替代实现

-ffast math
导致定义预处理器宏
\u FAST\u math\u

它只是一个功能测试宏,也就是说,您可以使用条件编译,具体取决于您是否指定了
-ffast math

#如果已定义(uuu FAST\u MATH)
/*要与-ffast math一起使用的代码*/
#否则
/*与-fno快速数学一起使用的代码*/
#endif/*-ffast数学*/
在大多数情况下,您不需要条件编译,但如果需要,您手头有一个宏,不需要在代码中或命令行上的per
-D
中定义它

此外,一些(系统)头可能依赖于它,并使用更快的代码,前提是
-ffast math
处于启用状态

更常见的此类宏是
\uuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。前者是在启用优化时定义的(
-Og
-O1
-O2
-Os
,…),后者是在根据
-Os
进行大小优化时定义的

注意:只有当
-ffast math
作为多库选项引入时,在标准库中使用这些选项才会如预期的那样起作用,因此指定它将链接libc、libm、libstdc++等的不同版本,就像
-m32
/
-m64
一样。您可以使用
gcc-print multi-lib
显示多库布局,该布局在我的x86_64上生成:

。;
32;@m32
这意味着我们有两种变体,一种是默认变体,另一种是使用
-m32
拾取的变体

-ffast math
导致定义预处理器宏
\u FAST\u math\u

它只是一个功能测试宏,也就是说,您可以使用条件编译,具体取决于您是否指定了
-ffast math

#如果已定义(uuu FAST\u MATH)
/*要与-ffast math一起使用的代码*/
#否则
/*与-fno快速数学一起使用的代码*/
#endif/*-ffast数学*/
在大多数情况下,您不需要条件编译,但如果需要,您手头有一个宏,不需要在代码中或命令行上的per
-D
中定义它

此外,一些(系统)头可能依赖于它,并使用更快的代码,前提是
-ffast math
处于启用状态

更常见的此类宏是
\uuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。前者是在启用优化时定义的(
-Og
-O1
-O2
-Os
,…),后者是在根据
-Os
进行大小优化时定义的

注意:只有当
-ffast math
作为多库选项引入时,在标准库中使用这些选项才会如预期的那样起作用,因此指定它将链接libc、libm、libstdc++等的不同版本,就像
-m32
/
-m64
一样。您可以使用
gcc-print multi-lib
显示多库布局,该布局在我的x86_64上生成:

。;
32;@m32

这意味着我们有两个变量,一个是默认变量,另一个是使用
-m32

拾取的变量。如果您使用
-ffast math
,则定义了
\uu FAST\u math\uuuu
。这可能就是它的全部,它没有进一步的影响。我猜页眉math.h在某处包含了一些#ifdef u FAST u math?此外,我仍然认为编译器内部的某些东西与-ffast-math的行为不同。答案中有很多关于该标志实际作用的信息。@Uli:的确,
\ifdef\uu FAST\u math\uu
出现在math.h、x86\u 64-linux-gnu/bits/mathinline.h以及更多位置。它也出现在独立的项目中,如Eigen3或boost/math。如果它是细粒度控件,您可能需要显式调用特定的库函数。例如,对于每个数学函数的具体实现,该库有许多不同的入口点。它具有SVID、X/OPEN或POSIX/ANSI版本的不同函数。但是,您可能会失去可移植性。如果您使用
-ffast math
,则定义了
\uu FAST\uu math\uuu
。这可能就是它的全部,它没有进一步的影响。我猜页眉math.h在某处包含了一些#ifdef u FAST u math?此外,我仍然认为编译器内部的某些东西与-ffast-math的行为不同。答案中有很多关于该标志实际作用的信息。@Uli:的确,
\ifdef\uu FAST\u math\uu
出现在math.h、x86\u 64-linux-gnu/bits/mathinline.h以及更多位置。它也出现在独立的项目中,如Eigen3或boost/math
#include <math.h>