web-dev-qa-db-ja.com

M_PIはmath.hで機能しますが、Visual Studioのcmathでは機能しません

私は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を定義すると動作します。なぜこれが起こっているのか?

80
hyperknot

興味深いことに、私は私のアプリでこれをチェックしましたが、同じエラーが発生しました。

_USE_MATH_DEFINESをundefしていないものがあるかどうかを確認するためにヘッダーをチェックするのにしばらく費やしましたが、何も見つかりませんでした。

だから私は

#define _USE_MATH_DEFINES
#include <cmath>

私のファイルの最初のものになるように(私はPCHを使用しないので、もしあなたが#include "stdafx.h"の後にそれを持たなければならないでしょう)、突然完全にコンパイルします。

ページの上に移動してみてください。しかし、これが問題を引き起こす理由についてはまったく不明です。

編集:考え出した。 #include <math.h>は、cmathのヘッダーガード内で発生します。つまり、#includesのリストの上位にあるものには、#defineが指定されていないcmathが含まれます。 math.hは、M_PIなどを追加するように変更された定義に再び含めることができるように特別に設計されています。これはcmathには当てはまりません。そのため、他のものを含める前に#define _USE_MATH_DEFINESを確認する必要があります。それがあなたのためにそれをクリアすることを願っています:)

math.hだけを含めることに失敗すると、既に指摘したように非標準のC/C++を使用しています:)

編集2:または、Davidがコメントで指摘しているように、値を定義する定数を自分で作成してください。

100
Goz

スイッチ/ D_USE_MATH_DEFINESをコンパイルコマンドラインに追加するか、プロジェクト設定でマクロを定義することを検討してください。これにより、シンボルがインクルードファイルとソースファイルの到達可能なすべての暗い隅にドラッグされ、複数のプラットフォームでソースがクリーンになります。プロジェクト全体でグローバルに設定した場合、後で新しいファイルで忘れることはありません。

10
Thinkeye

これは私のために働く:

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

using namespace std;

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

    return 0;
}

pi like is should:cl /O2 main.cpp /link /out:test.exeをコンパイルして出力します。

投稿したコードとコンパイルしようとしているコードに不一致がなければなりません。

#defineの前に、プリコンパイル済みヘッダーが取り込まれていないことを確認してください。

7
rubenvb

これは、コンソールまたはWindowsアプリをビルドするときのVS Community 2015および2017の問題です。プロジェクトがプリコンパイル済みヘッダーを使用して作成されている場合、プリコンパイル済みヘッダーは、#define _USE_MATH_DEFINESが最初であっても、#includeのいずれかbeforeにロードされるようです。行、それはコンパイルしません。 #cmathの代わりにmath.hを含めても違いはありません。

私が見つけることができる唯一の解決策は、空のプロジェクトから開始するか(単純なコンソールまたは組み込みシステムアプリの場合)、コマンドライン引数に/ Y-を追加して、プリコンパイル済みヘッダーの読み込みをオフにすることです。

プリコンパイル済みヘッダーを無効にする方法については、例を参照してください https://msdn.Microsoft.com/en-us/library/1hy7a92h.aspx

MSがこれを変更/修正してくれるといいですね。私は大規模な大学でプログラミングの入門コースを教えていますが、初心者にこれを説明するのは、彼らが間違いを犯して午後ほど苦労するまで決して沈みません。

4
user3533658

数学定数 に関するMicrosoftのドキュメントによると:

プロジェクトがリリースモードでビルドされる場合、ファイルATLComTime.hにはmath.hが含まれます。 ATLComTime.hも含むプロジェクトで1つ以上の数学定数を使用する場合、_USE_MATH_DEFINESを含める前にATLComTime.hを定義する必要があります。

ファイルATLComTime.hをプロジェクトに間接的に含めることができます。私の場合、含めることができる順序は次のとおりです。

プロジェクトの"stdafx.h"<afxdtctl.h><afxdisp.h><ATLComTime.h><math.h>

0