【问题标题】:Using M_PI with C89 standard将 M_PI 与 C89 标准一起使用
【发布时间】:2011-02-15 18:34:58
【问题描述】:

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

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

【问题讨论】:

    标签: c math c89


    【解决方案1】:

    符合标准的库文件math.h 不仅不需要,而且实际上不得默认定义M_PI。在这种情况下,“默认情况下”意味着M_PI 只能通过特定于编译器的技巧来定义,通常是通过使用保留标识符来定义未定义的行为。

    只需要自己定义常量(M_PI这个名字你可以随意使用,但是如果你想用不符合标准的编译器来编译代码,你必须先检查M_PI没有被定义) .为约定起见,请勿将M_PI 定义为 pi(的近似值)以外的任何内容。

    【讨论】:

    • @Jason S:这只是标准库实现不允许“污染”命名空间(即,必须按照标准只使用保留标识符)这一事实的结果。
    • 是这样吗?这意味着 C 实现永远不能同时符合 C89 和 C99,因为 C99 将标识符添加到库中。
    • @larsmans:C99 小心地添加为 C89 中的实现保留的标识符(具体参见 C89 中的第 4.13 节 FUTURE LIBRARY DIRECTIONS),或在 C89 中未定义的新头文件中。但是,在 C89 和 C99 之间存在一些不同库行为的极端情况 - 例如 strtod() 在 C99 中必须处理十六进制浮点,而在 C89 中则不能。
    • @FredFoo 没错;不能同时符合 C89 和 C99。这就是为什么我们有编译器开关来选择其中一个。 C89 实现可以提供一些 C99 特性作为符合标准的扩展;明显的情况是允许程序调用 C99 函数,或使用 long long(只要发出诊断信息)。
    【解决方案2】:

    我会去

    #ifndef M_PI
    #    define M_PI 3.14159265358979323846
    #endif
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        那些启用的部分并未定义为 ISO C 标准的一部分,但这与不是标准 C 语言不同,语言和库在 C 中是独立的实体。它与 C89 的兼容程度不亚于您在自己的标头中定义自己的宏。

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

        -std=c89 -D_USE_MATH_DEFINES
        

        如果您遇到未定义 M_PI 的 math.h 实现,则无需修改代码即可轻松修复,类似地使用命令行定义的宏:

        -std=c89 -DM_PI=3.14159265358979323846
        

        【讨论】:

        • _USE_* 是 glibc 内部的一部分,由于定义了一些公共功能测试宏,因此只能定义为 features.h。使用-D_GNU_SOURCE 或更便携,-D_XOPEN_SOURCE=700 或类似。
        • @R..:是 OP 在 StackOverflow 上的其他地方找到宏后决定使用该宏 - 不幸的是,他未能指定位置。 GNU documentation 说要定义“_BSD_SOURCE_XOPEN_SOURCE=500,或更通用的功能选择宏”,而Microsoft's C Runtime documentation 说要定义_USE_MATH_DEFINES,所以我坚持使用后者只是为了兼容性;这个问题没有提到任何特定的编译器。
        猜你喜欢
        • 1970-01-01
        • 2012-04-16
        • 1970-01-01
        • 1970-01-01
        • 2016-09-25
        • 2011-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多