M_PI适用于math.h,但不适用于Visual Studio中的cmath

时间:2011-07-03 15:37:28

标签: c++ visual-studio visual-studio-2010

我正在使用Visual Studio 2010.我已经读过,在C ++中,最好使用<cmath>而不是<math.h>

但是在我编写的程序中(Win32控制台应用程序,空项目),如果我写:

#define _USE_MATH_DEFINES
#include <math.h>

它编译,而如果我写

#define _USE_MATH_DEFINES
#include <cmath>

它以

失败
  

错误C2065:'M_PI':未声明的标识符

这是正常的吗?如果我使用cmath或math.h是否重要?如果是,我怎样才能使用cmath?

UPDATE :如果我在GUI中定义_USE_MATH_DEFINES,它可以正常工作。任何线索为什么会发生这种情况?

6 个答案:

答案 0 :(得分:97)

有趣的是,我在我的应用程序上检查了这个,我得到了同样的错误。

我花了一些时间检查标题,看看是否有任何东西未找到_USE_MATH_DEFINES并且什么也没找到。

所以我移动了

#define _USE_MATH_DEFINES
#include <cmath>

是我文件中的第一件事(我不使用PCHs,所以如果你是你必须在#include "stdafx.h"之后拥有它)并且突然它完全编译。

尝试将其向上移动到页面上方。完全不确定为什么会导致问题。

编辑:想出来。 #include <math.h>发生在cmath的标题保护中。这意味着#includes列表中较高的位置包含cmath而未指定#definemath.h是专门设计的,您可以使用现在已更改的定义再次添加M_PI等。cmath不是这种情况。因此,在包含其他内容之前,您需要确保#define _USE_MATH_DEFINES。希望能为你清除它:)

如果没有,只是包含math.h你正在使用的非标准C / C ++已经指出:)

编辑2 :或者正如David在评论中指出的那样,只需要自己定义一个值,然后你就可以获得更多可移植性:)

答案 1 :(得分:10)

考虑将开关/ D_USE_MATH_DEFINES添加到编译命令行,或者在项目设置中定义宏。这会将符号拖动到包含源文件和源文件的所有可到达黑暗角落,从而使源清理多个平台。如果您为整个项目全局设置它,您将不会在以后的新文件中忘记它。

答案 2 :(得分:7)

这对我有用:

#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>

using namespace std;

int main()
{
    cout << M_PI << endl;

    return 0;
}

编译并打印pi,应该:cl /O2 main.cpp /link /out:test.exe

您发布的代码与您尝试编译的代码之间必定存在不匹配。

请确保在#define之前没有预先编译好的标题。

答案 3 :(得分:4)

在构建控制台或Windows应用程序时,VS社区2015和2017仍然是一个问题。 如果项目是使用预编译的头文件创建的,那么预编译的头文件显然是在 任何#includes之前加载的,所以即使#define _USE_MATH_DEFINES是第一行,它也不会编译。 #including math.h而不是cmath没有什么区别。

我能找到的唯一解决方案是从空项目(对于简单的控制台或嵌入式系统应用程序)开始,或者将/ Y-添加到命令行参数,这将关闭预编译头的加载。

有关禁用预编译标头的信息,请参阅示例 https://msdn.microsoft.com/en-us/library/1hy7a92h.aspx

如果MS会改变/解决这个问题会很好。我在一所大型大学教授入门编程课程,向新手解释这些课程从未陷入困境,直到他们犯了错误并在一个下午左右挣扎。

答案 4 :(得分:1)

有了CMake,就可以了

add_compile_definitions(_USE_MATH_DEFINES)

CMakeLists.txt中。

答案 5 :(得分:0)

根据user7860670的建议,右键单击项目,选择属性,导航到C / C ++-> Preprocessor,并将_USE_MATH_DEFINES添加到Preprocessor Definitions。

那对我有用。