无法找到 -std=c99 的 math.h 常量?

3

我有一个简单的测试代码,t.c

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

int main(){
  printf("%f\n", M_LN10);
}

在我的某个系统上(OS X 10.8.4,GCC 4.8.1),这个程序可以成功编译。但是奇怪的是,在另一个系统(Ubuntu 12.04.2 LTS,GCC 4.6.3)中,使用 gcc t.c 可以成功编译,但如果我使用 gcc -std=c99 t.c 编译就会出现以下错误:

t.c: In function ‘main’:
t.c:5:18: error: ‘M_LN10’ undeclared (first use in this function)
t.c:5:18: note: each undeclared identifier is reported only once 
for each function it appears in

我不明白为什么GCC在默认的C标准下可以找到并接受math.h中的M_LN10,但如果强制使用C99则不能。你知道这是怎么回事吗?


1
gcc的默认“标准”并不是标准。它是gnu90,即“1990年C标准加上GNU扩展”。在没有设置_XOPEN_SOURCE的情况下使用XSI math.h定义是GNU扩展,在指定实际标准时不可用。 - rici
@rici 谢谢,这增加了一些清晰度。我习惯于 -std=c99 添加 扩展,而不是去除它们。 - Douglas B. Staple
添加扩展和添加标准是有区别的 :) (或者换句话说,新标准是对旧标准的进步 - 希望如此 - 但不是扩展。) - rici
C标准对M_*常量没有任何规定。它是由GNU C、BSD和其他标准定义的,但不是C标准 - 因此,当您指定不是GNU的内容时,gcc会禁用此功能,以更接近标准。 - keltar
1个回答

8

在您的GCC命令中添加-D_BSD_SOURCE-D_XOPEN_SOURCE。例如:gcc -std=c99 -D_XOPEN_SOURCE t.c

查看我的系统上的math.h文件后,发现M_LN10定义如下:

#if defined __USE_BSD || defined __USE_XOPEN
# define M_LN10         2.30258509299404568402  /* log_e 10 */
#endif

2
请阅读man feature_test_macrosinfo libc“Feature Test Macros”,以便能够提供更好的建议。以__开头的宏几乎从来不打算公开。(在你提到它们之前,请注意__FILE____LINE__是历史上的异常情况。) - rici
@shanet 你不觉得这样的定义会有其他副作用吗? - user66363
@rici 今天我学到了一些东西。 :) 我用适当的宏更新了我的答案。谢谢。 - shanet
1
是的,你说得对;添加“-D_BSD_SOURCE”就可以了。在OS X系统上,“math.h”声明了“M_LN10”,而没有使用“ifdef”…很奇怪。 - Douglas B. Staple
1
@DouglasB.Staple,OS X上也是用gcc编译吗?有点奇怪,不过这也有一定的道理,因为OS X内核与BSD高度相关。 - keltar
@keltar 是的,在OS X上,GCC除了包含“math.h”以获取“M_”常量之外,不需要任何声明。这在“/usr/include/math.h”和MacPorts提供的版本“/opt/.../math.h”中都是如此。 - Douglas B. Staple

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