M_PI는 math.h에서는 작동하지만 Visual Studio의 cmath에서는 작동하지 않습니다.


95

나는 C ++에서 그것을 사용하는 것이 낫다는 것을 읽고 Visual Studio 2010에서 Visual Studio 2010을 사용하고 있습니다 <cmath>보다는이 <math.h>.

그러나 프로그램에서 다음과 같이 작성하면 (Win32 콘솔 응용 프로그램, 빈 프로젝트) 작성하려고합니다.

#define _USE_MATH_DEFINES
#include <math.h>

컴파일하는 동안 내가 쓰면

#define _USE_MATH_DEFINES
#include <cmath>

그것은 실패한다

오류 C2065 : 'M_PI': 선언되지 않은 식별자

정상인가요? cmath 또는 math.h를 사용하는 것이 중요합니까? 그렇다면 cmath에서 어떻게 작동하도록 할 수 있습니까?

업데이트 : GUI에서 _USE_MATH_DEFINES를 정의하면 작동합니다. 왜 이런 일이 발생하는지 알 수 있습니까?


소스 파일이 .c 또는 .cpp입니까?
Swiss

1
스위스 : 여기서는 중요하지 않습니다.
rubenvb 2011

매우 이상합니다 ... 나는 VS2010과 동일한 문제가 있음을 확인할 수 있습니다 ... 정의가 통과하는 것을 막는 것이 무엇인지 조사하고 있습니다 ... 어딘가에 정의되지 않은 것이어야합니다 ... 그러나 나는 어디에서 찾을 수 없습니다
Goz

x86에서는 오류 C2065를 표시합니다. x64에서는 오류가 없습니다.
user2616989

답변:


117

흥미롭게도 내 앱에서 이것을 확인했는데 동일한 오류가 발생했습니다.

나는 헤더를 통해 undef'ing이 있는지 확인 _USE_MATH_DEFINES하고 아무것도 찾지 못했습니다.

그래서 나는

#define _USE_MATH_DEFINES
#include <cmath>

내 파일의 첫 번째 항목이 되려면 (PCH를 사용하지 않으므로 #include "stdafx.h") 뒤에 있어야 하며 갑자기 완벽하게 컴파일됩니다.

페이지 위로 이동해보십시오. 이것이 문제를 일으키는 이유에 대해 완전히 확신하지 못합니다.

편집 : 그것을 알아 냈습니다. 는 #include <math.h>cmath의 헤더 가드 내에서 발생합니다. 이것은 #includes 목록의 상위에있는 cmath것이 #define지정 되지 않고 포함된다는 것을 의미 합니다. math.h지금 추가로 변경 정의하는 것이 당신이 다시 포함 할 수 있도록 특별히 설계 M_PI이의 경우 NOT 등등 cmath. 따라서 #define _USE_MATH_DEFINES다른 항목을 포함하기 전에 확인해야합니다 . 그것이 당신을 위해 그것을 정리하기를 바랍니다 :)

math.h이미 지적한대로 비표준 C / C ++를 사용 하고 있다는 것을 포함하지 않으면 :)

편집 2 : 또는 David가 주석에서 지적했듯이 값을 정의하는 상수로 만들고 어쨌든 더 이식 가능한 것이 있습니다 :)


전에 정의한 것은 이전 stdafx.h에이 동작에 직면 한 OP 문제입니다.
Alok Save

@Als : 아니 그게 아니에요 ... 그것을 깨고 위의 편집에서 설명했습니다 :)
Goz

글쎄, 그것이 가장 먼저해야 할 일이었습니다. OP에게 동일한 작업을 요청한 다른 모든 heasder보다 우선적으로 유지하십시오 .... 귀하의 답변이 표준 헤더 앞에 있어야하는 실제 이유를 말하고 있기 때문에 어쨌든 내 답변을 삭제할 것입니다.
Alok Save

3
예를 들어, 수행하기 전에 #include <math.h>에 다른 일이 발생한 경우이 동작이 발생합니다. 즉, 표준에는 <cmath>가 <math.h>를 포함해야하거나 <math.h>에서 비표준 정의를 활성화해야한다는 내용이 없습니다. 불행히도 M_PI는 표준이 아닙니다. 이식성을 위해 가장 좋은 방법은 직접 정의하는 것입니다. 더 나은 방법 const static double은 #defined 값 이 아닌 값으로 만드는 것 입니다.
David Hammen 2011

1
@ 데이비드 Hammen : 자신이 :) 확실히 대부분의 휴대용 옵션을 정의 .. 합의
고즈

14

컴파일 명령 줄에 / D_USE_MATH_DEFINES 스위치를 추가하거나 프로젝트 설정에서 매크로를 정의하는 것이 좋습니다. 이렇게하면 포함 및 소스 파일의 도달 할 수있는 모든 어두운 모서리로 심볼을 드래그하여 여러 플랫폼에서 소스를 깨끗하게 유지합니다. 전체 프로젝트에 대해 전역 적으로 설정하면 나중에 새 파일에서 잊지 않을 것입니다.


VisualStudio에서 작동 할 때 좋은 대답 일 수 있지만 Matlab mex 명령 줄을 통해 컴파일 할 때 문제가 해결되지 않았다는 점에 유의하십시오 ( mex -D_USE_MATH_DEFINES). 만 추가 /Y-... 일부 matlab에 mexoptions 파일에 smewhere을 도왔
aka.nice

9

이것은 나를 위해 작동합니다.

#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..

게시 한 코드와 컴파일하려는 코드가 일치하지 않아야합니다.

.NET Framework 이전에 가져온 미리 컴파일 된 헤더가 없는지 확인하십시오 #define.


어떤 버전의 VisualStudio를 사용하고 있습니까?
Goz

Visual C ++ 2010 Express Edition의 명령 줄 컴파일러를 사용하면 동일한 프로그램이 잘 작동했습니다. 유일한 차이점은 <iostream>의 std :: cout 대신 <cstdio>의 std :: printf ()를 사용했다는 것입니다.

4
그래 내가 알아 냈어 ... 그 이유는 maths.h가 cmath의 헤더 가드 내에서 호출 되었기 때문입니다 ... 그래서 maths.h는 이미 #define 세트없이 이전 헤더에서 포함되었습니다. :)
Goz

4

이것은 콘솔 또는 Windows 앱을 빌드 할 때 VS Community 2015 및 2017에서 여전히 문제입니다. 프로젝트가 미리 컴파일 된 헤더로 생성 된 경우 미리 컴파일 된 헤더가 #includes 앞에 로드 되므로 #define _USE_MATH_DEFINES가 첫 번째 줄이더라도 컴파일되지 않습니다. #cmath 대신 math.h를 포함해도 차이가 없습니다.

내가 찾을 수있는 유일한 해결책은 빈 프로젝트 (간단한 콘솔 또는 임베디드 시스템 앱의 경우)에서 시작하거나 / Y-를 명령 줄 인수에 추가하여 미리 컴파일 된 헤더의로드를 끄는 것입니다.

미리 컴파일 된 헤더 비활성화에 대한 자세한 내용은 https://msdn.microsoft.com/en-us/library/1hy7a92h.aspx를 참조하십시오.

MS가 이것을 변경 / 수정하면 좋을 것입니다. 나는 큰 대학에서 입문 프로그래밍 과정을 가르치고 있으며, 초보자들에게 이것을 설명하는 것은 그들이 실수를 저지르고 오후 정도의 어려움을 겪을 때까지 결코 빠져들지 않습니다.


내가 Y- / 해킹 C 코드, 나를 위해 일한 것을 확인 사용법 #include <math.h>
aka.nice

1
이것은 VS에서 전혀 문제가되지 않습니다. _USE_MATH_DEFINES헤더를 포함하기 전에 정의해야합니다. 일반적으로 프로젝트 설정 또는 구성 헤더를 통해. 단순히 첫 번째 줄에두면 모든 헤더보다 먼저 정의된다고 가정하는 것은 잘못되었습니다.
user7860670

1

수학 상수 에 대한 Microsoft 문서에 따르면 :

이 파일 ATLComTime.h에는 math.h프로젝트가 릴리스 모드에서 빌드 된 경우가 포함 됩니다. 을 포함하는 프로젝트에서 하나 이상의 수학 상수를 사용하는 경우 포함 하기 전에 ATLComTime.h정의해야합니다 ._USE_MATH_DEFINESATLComTime.h

파일 ATLComTime.h이 프로젝트에 간접적으로 포함될 수 있습니다. 제 경우에는 다음과 같은 순서를 포함 할 수 있습니다.

프로젝트의 "stdafx.h"<afxdtctl.h><afxdisp.h><ATLComTime.h><math.h>


이것은 / Y- (stdafx.h 비활성화)가 문제를 해결하는 이유를 설명 할 수 있지만 -D_USE_MATH_DEFINES기본 컴파일러 설정을 제공하는 것이 문제를 해결하는 데 충분하지 않은 이유를 설명 할 수 있습니다. 컴파일은 내 자신을 위해 Matlab mex 명령을 통해 이루어 졌기 때문에 문제는 아니에요 분명 추적하는 것을 ...
aka.nice

1

CMake를 사용하면

add_compile_definitions(_USE_MATH_DEFINES)

에서 CMakeLists.txt.


0

user7860670이 제안한대로 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 속성을 선택한 다음 C / C ++-> 전처리기로 이동 _USE_MATH_DEFINES하여 전 처리기 정의에 추가 합니다.

그게 저에게 효과적이었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.