M_PI在gcc --std=c11下不可用,但在--std=gnu11下可用吗?

14

我注意到 c11 上没有定义 M_PI。通过查看 /usr/include/math.h,我发现只有在以下情况下才定义了 M_PI

#if !defined(__STRICT_ANSI__) || ((_XOPEN_SOURCE - 0) >= 500)
...
#define M_PI 3.1415...
#endif 

此外,在glibcmath.h中,__STRICT_ANSI__被替换为__USE_MISC。我完全不知所措。

--std=c11math.h中定义的常量之间有什么关联吗?

debian发行版中应该考虑哪个libc?

顺便提一下,M_PIc99gnu11中都有定义...


你的问题明显是关于C11而不是C++11,为什么要使用c++11标签? - juhist
2
有的,而且您的帖子已经被编辑为c11标签,而不是c++11。 - juhist
3个回答

24
简单来说,标准C中没有定义M_PI常量。如果您想符合标准,请自己提供定义。
C编译器不能引入这样的常量而不破坏合法的C程序(名称未被保留,可能被用作标识符),因此它们只是被定义为扩展。
当使用-std=c99时,GCC 4.9不定义M_PI,但是在使用-std=gnu99时进行了定义

它虽然是在“c99”中定义的。 - nowox
2
@coin 这不应该是这样的 - C99也没有定义M_PI - milleniumbug
1
GCC 的默认值是 gnu90。5.1.0(尚未发布)将默认为 gnu11 - cremno
1
@coin:它使用与不同或没有“-std”选项相同的libc(通常是glibc,但不一定。例如在Windows上)。还可以阅读http://man7.org/linux/man-pages/man7/feature_test_macros.7.html和https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html以获取更多信息。 - cremno
3
为什么要这样麻烦呢?如果你需要更多的功能,就使用带有扩展名的“-std=gnu99”选项;如果你需要可移植性,并且不想意外地限制自己只能使用一个编译器,那么就使用“-std=c99”选项,不需要扩展。 - milleniumbug
显示剩余2条评论

9
如果您只需要M_PI,而在寻找包含POSIX / XOPEN特性测试宏等更全面的答案时,可以采用以下临时解决方案:
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif

这是“1.20”格式,对于80位扩展类型的“往返”表示也足够了。双精度为“1.16”。对于128位四倍精度:

#define M_PI (3.14159265358979323846264338327950288)

“1.35”是用于往返精度的格式。这意味着如果您想打印一个浮点double,并在读回来时恢复相同的值,则应使用“%+1.16”进行printf函数等操作。您可能会说double没有17个有效数字,但是如果您想要恢复值,则那些数字并不是“垃圾”。无论如何,有比这更好的资源可用

对于正确的1.16,应该写成+1。顺便问一句:你认为有很多圆周率数字(比如80位)有什么不好的地方吗? - chux - Reinstate Monica
1
@chux - 我想不出来。至少gcc包含gmp / mpfr / mpc库来处理所有多精度问题,具有正确(可选择的)舍入模式等。如果将80位数字PI值分配给单精度浮点数,我希望它能做正确的事情。不知道这个页面有多新。我不知道clang的方法。 - Brett Hale

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接