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

我正在使用 VisualStudio2010。我读到在 C + + 中最好使用 <cmath>而不是 <math.h>

But in the program I am trying to write (Win32 console application, empty project) if I write:

#define _USE_MATH_DEFINES
#include <math.h>

它会编译,而如果我写

#define _USE_MATH_DEFINES
#include <cmath>

失败了

Error C2065: M _ PI’: 未声明的标识符

这正常吗?我用数学还是计算有关系吗?如果是,我怎样才能使它与计算机数学工作?

更新 : 如果我在 GUI 中定义 _ USE _ MATH _ DEFINES,它会工作?

169919 次浏览

这对我有用:

#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之前没有预编译的头被拉进来。

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

I spent a while checking through headers to see if there was anything undef'ing the _USE_MATH_DEFINES and found nothing.

所以我把

#define _USE_MATH_DEFINES
#include <cmath>

成为我的文件中的第一件事(我不使用 PCHs,所以如果你是你将不得不有它之后的 #include "stdafx.h") ,突然它完美地编译。

Try moving it higher up the page. Totally unsure as to why this would cause issues though.

编辑 : 弄清楚了。#include <math.h>出现在 cmath 的头保护中。这意味着在 # include 列表的上面包含了没有指定 #definecmathmath.h是专门设计的,以便您可以包括它再次与定义现在改为添加 M_PI等。这不是 cmath的情况。所以你需要确保你的 #define _USE_MATH_DEFINES之前,你包括任何其他。希望这能为你澄清:)

如果没有包含 math.h,那么就是在使用非标准的 C/C + + ,正如前面已经指出的那样:)

编辑2 : 或者就像 David 在评论中指出的那样,只需要让自己成为一个定义值的常量,无论如何,你就有了更便携的东西:)

Consider adding the switch /D_USE_MATH_DEFINES to your compilation command line, or to define the macro in the project settings. This will drag the symbol to all reachable dark corners of include and source files leaving your source clean for multiple platforms. If you set it globally for the whole project, you will not forget it later in a new file(s).

在 VSCommunity2015和2017年构建控制台或 Windows 应用程序时,这仍然是一个问题。 如果项目是用预编译头创建的,那么预编译头显然加载了 之前中的 # include,所以即使 # Definition _ USE _ MATH _ DEFINES 是第一行,它也不会编译。包括数学,而不是数学,没有区别。

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

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

如果微软能改变/修复这个问题就好了。我在一所大型大学教授编程入门课程,向新手解释这个问题,直到他们犯了错误,并为此纠结了一个下午左右,他们才能理解。

根据微软关于 数学常数的文档:

当项目以发布模式构建时,文件 ATLComTime.h包括 math.h。如果在包含 ATLComTime.h的项目中使用一个或多个数学常数,则必须在包含 ATLComTime.h之前定义 _USE_MATH_DEFINES

文件 ATLComTime.h可能间接包含在您的项目中。在我的案例中,包含的一个可能顺序如下:

项目的 "stdafx.h"<afxdtctl.h><afxdisp.h><ATLComTime.h><math.h>

As suggested by user7860670, right-click on the project, select properties, navigate to C/C++ -> Preprocessor and add _USE_MATH_DEFINES to the Preprocessor Definitions.

我就是这么做的。

和 CMake 在一起

add_compile_definitions(_USE_MATH_DEFINES)

CMakeLists.txt