M_PI работает с math.h, но не с cmath в Visual Studio - PullRequest
78 голосов
/ 03 июля 2011

Я использую 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 : если я определю _USE_MATH_DEFINES в GUI, это будет работать.Любая подсказка, почему это происходит?

Ответы [ 5 ]

97 голосов
/ 03 июля 2011

Интересно, что я проверил это в своем приложении и получил ту же ошибку.

Я потратил некоторое время, проверяя заголовки, чтобы выяснить, не было ли что-то, что не соответствует _USE_MATH_DEFINES, и ничего не нашел.

Так что я переместил

#define _USE_MATH_DEFINES
#include <cmath>

, чтобы быть первым в моем файле (я не использую PCH, поэтому, если вы, у вас будет его после #include "stdafx.h") ивдруг он идеально скомпилируется.

Попробуйте переместить его выше на страницу.Полностью неуверенный относительно того, почему это могло вызвать проблемы.

Редактировать : понял это.#include <math.h> встречается в охранниках заголовка cmath.Это означает, что что-то более высокое в списке #include включает cmath без указания #define.math.h специально разработан для того, чтобы вы могли снова включить его в то определение, которое теперь изменено, чтобы добавить M_PI и т. Д. Это НЕ в случае с cmath.Поэтому вам нужно убедиться, что вы #define _USE_MATH_DEFINES, прежде чем включать что-либо еще.Надеюсь, что это прояснит для вас:)

Если вы просто не включите math.h, вы используете нестандартный C / C ++, как уже указывалось:)

Edit 2 : Или, как указывает Дэвид в комментариях, просто сделайте себя константой, определяющей значение, и вы все равно получите что-то более переносимое:)

10 голосов
/ 19 февраля 2014

Попробуйте добавить ключ / D_USE_MATH_DEFINES в командную строку вашей компиляции или определить макрос в настройках проекта. Это перетянет символ во все доступные темные углы включаемых и исходных файлов, оставляя исходный код чистым для нескольких платформ. Если вы установите его глобально для всего проекта, вы не забудете его позже в новом файле (ах).

7 голосов
/ 03 июля 2011

Это работает для меня:

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

нет предварительно скомпилированных заголовков.
4 голосов
/ 23 марта 2018

Это все еще проблема в VS Community 2015 и 2017 при создании консольных или Windows-приложений.Если проект создается с предварительно скомпилированными заголовками, то предварительно скомпилированные заголовки, очевидно, загружаются за до любого из #include, поэтому даже если #define _USE_MATH_DEFINES является первой строкой, он не скомпилируется.#include math.h вместо cmath не имеет значения.

Единственные решения, которые я могу найти, - это начать с пустого проекта (для простых приложений консоли или встроенных системных приложений) или добавить / Y- каргументы командной строки, которые отключают загрузку предварительно скомпилированных заголовков.

Для получения информации об отключении предварительно скомпилированных заголовков см., например, https://msdn.microsoft.com/en-us/library/1hy7a92h.aspx

Было бы хорошо, если бы MS изменился/почини это.Я преподаю вводные курсы по программированию в крупном университете, и объяснение этого новичкам никогда не дойдет до тех пор, пока они не совершат ошибку и не будут бороться с ней в течение дня или около того.

0 голосов
/ 12 марта 2019

Согласно документации Microsoft о математических константах :

Файл ATLComTime.h включает math.h, когда ваш проект построен в режиме выпуска.Если вы используете одну или несколько математических констант в проекте, который также включает ATLComTime.h, вы должны определить _USE_MATH_DEFINES, прежде чем включать ATLComTime.h.

Файл ATLComTime.h может быть включен косвеннов вашем проекте.В моем случае одним из возможных порядков включения было следующее:

проекта "stdafx.h"<afxdtctl.h><afxdisp.h><ATLComTime.h><math.h>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...