使用M_PI和C89标准

rob*_*ntw 23 c math c89

我正在使用C并尝试访问常量M_PI(3.14159 ...).我已导入math.h头文件,但M_PI常量仍未定义.通过对StackOverflow的一些搜索,我发现我需要添加#define _USE_MATH_DEFINES到我的代码中(参见下面的示例代码).这在正常编译时工作正常,但我需要能够使用std=c89标志编译我正在做的工作.

我应该如何从某些C89代码访问M_PI?

eq-*_*eq- 38

math.h不仅要求符合标准的库文件,而且实际上不能M_PI默认定义.在此上下文中,"默认情况下"意味着M_PI必须仅通过特定于编译器的技巧来定义,通常通过使用保留标识符来定义未定义的行为.

只需自己定义常量(您可以M_PI自由使用该名称,但是如果您希望能够使用不符合的编译器编译代码,则必须首先检查M_PI尚未定义的代码).为了惯例,不要将其定义M_PI为pi的近似值(近似值).

  • @Jason S:这只是标准库实现不允许"污染"命名空间(即必须按标准使用保留标识符)这一事实的结果. (4认同)
  • @larsmans:C99小心地添加为C89中的实现保留的标识符(特别参见C89中的第4.13节"未来库方向"),或者在C89中未定义的新头文件中.但是在C89和C99之间存在一些不同库行为的极端情况 - 例如`strtod()`它必须处理C99中的十六进制浮点而不能处理C89. (2认同)

Sve*_*ach 25

我会去的

#ifndef M_PI
#    define M_PI 3.14159265358979323846
#endif
Run Code Online (Sandbox Code Playgroud)

  • @user16217248正如您在第一个答案中看到的那样,符合要求的实现实际上_不能_定义“M_PI”,因此可以保证它没有定义。我仍然会使用这个答案中的代码,因为首先检查它是否已经定义没有什么坏处。 (2认同)

Mat*_*lia 9

M_PIC标准不要求它,它只是一个常见的扩展,所以如果你想成为标准,你就不应该依赖它.但是,您可以轻松地#define为它定义自己的,上次我检查它是一个通用常量,因此没有太多的混淆空间.:)


Cli*_*ord 8

我没看到这里的问题是什么; -std = c89和_USE_MATH_DEFINES之间没有不兼容性,一个定义了编译器将编译的语言,另一个定义了math.h的哪些部分被启用.

那些已启用的部分未被定义为ISO C标准库的一部分,但这与不是标准C语言不同,语言和库是C中的独立实体.它与C89一致,不会少于C89.如果您已在自己的标头中定义了自己的宏.

但是,我建议您在命令行而不是代码中定义宏:

-std=c89 -D_USE_MATH_DEFINES
Run Code Online (Sandbox Code Playgroud)

如果您遇到过没有定义M_PI的math.h实现,那么通过类似地使用命令行定义的宏,可以在不修改代码的情况下轻松修复:

-std=c89 -DM_PI=3.14159265358979323846
Run Code Online (Sandbox Code Playgroud)