web-dev-qa-db-fra.com

M_PI fonctionne avec math.h mais pas avec cmath dans Visual Studio

J'utilise Visual Studio 2010. J'ai lu qu'en C++, il est préférable d'utiliser <cmath> plutôt que <math.h>.

Mais dans le programme, j'essaie d'écrire (application console Win32, projet vide) si j'écris:

#define _USE_MATH_DEFINES
#include <math.h>

il compile, alors que si j'écris

#define _USE_MATH_DEFINES
#include <cmath>

il échoue avec

erreur C2065: 'M_PI': identifiant non déclaré

Est-ce normal? Est-ce important si j'utilise cmath ou math.h? Si oui, comment puis-je le faire fonctionner avec cmath?

UPDATE : si je définis _USE_MATH_DEFINES dans l'interface graphique, cela fonctionne. Une idée pourquoi cela se passe?

80
hyperknot

Fait intéressant, j'ai vérifié cela sur une de mes applications et j'ai eu la même erreur.

J'ai passé un certain temps à vérifier dans les en-têtes pour voir s'il y avait quelque chose qui défie le _USE_MATH_DEFINES Et je n'ai rien trouvé.

Alors j'ai déplacé le

#define _USE_MATH_DEFINES
#include <cmath>

pour être la première chose dans mon dossier (je n'utilise pas PCH, donc si vous l'êtes, vous devrez l'avoir après le #include "stdafx.h") et tout à coup, la compilation sera parfaite.

Essayez de le déplacer plus haut dans la page. Totalement incertain quant à pourquoi cela causerait des problèmes cependant.

Edit: Je l'ai compris. Le #include <math.h> Se produit dans les gardes d'en-tête de cmath. Cela signifie que quelque chose de plus haut dans la liste des #includes est d'inclure cmath sans le #define Spécifié. math.h Est spécialement conçu pour que vous puissiez l'inclure à nouveau avec cette définition maintenant modifiée pour ajouter M_PI Etc. Ce n'est PAS le cas avec cmath. Donc, vous devez vous assurer que vous avez #define _USE_MATH_DEFINES Avant d'inclure autre chose. J'espère que ça s'éclaircit pour vous :)

Si vous n'incluez que math.h, Vous utilisez un langage C/C++ non standard, comme indiqué plus haut :)

Edit 2: Ou, comme David le souligne dans les commentaires, créez-vous une constante qui définit la valeur et vous aurez quelque chose de plus portable en tout cas :)

100
Goz

Pensez à ajouter le commutateur/D_USE_MATH_DEFINES à votre ligne de commande de compilation ou à définir la macro dans les paramètres du projet. Cela fera glisser le symbole sur tous les coins sombres accessibles des fichiers d'inclusion et source, laissant votre source propre pour plusieurs plates-formes. Si vous le définissez globalement pour l'ensemble du projet, vous ne l'oublierez pas plus tard dans un nouveau fichier.

10
Thinkeye

Cela fonctionne pour moi:

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

using namespace std;

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

    return 0;
}

Compile et imprime pi comme il se doit: cl /O2 main.cpp /link /out:test.exe.

Il doit y avoir une discordance dans le code que vous avez posté et celui que vous essayez de compiler.

Assurez-vous qu'aucun en-tête précompilé n'a été inséré avant votre #define.

7
rubenvb

Ce problème persiste dans VS Community 2015 et 2017 lors de la création d'applications console ou Windows. Si le projet est créé avec des en-têtes précompilés, les en-têtes précompilés sont apparemment chargés avant l'un des #includes, donc même si le #define _USE_MATH_DEFINES est le premier en ligne, il ne compilera pas. # y compris math.h au lieu de cmath ne fait aucune différence.

Les seules solutions que je puisse trouver sont soit de démarrer à partir d'un projet vide (pour une console simple ou des applications système intégrées), soit d'ajouter/Y- aux arguments de ligne de commande, ce qui désactive le chargement des en-têtes précompilés.

Pour plus d'informations sur la désactivation des en-têtes précompilés, voir par exemple https://msdn.Microsoft.com/en-us/library/1hy7a92h.aspx

Ce serait bien si MS changeait/corrigeait cela. J'enseigne des cours d'introduction à la programmation dans une grande université et je ne l'explique jamais aux débutants tant qu'ils n'ont pas commis l'erreur et lutté pendant un après-midi environ.

4
user3533658

Selon la documentation de Microsoft concernant Constantes mathématiques :

Le fichier ATLComTime.h comprend math.h lorsque votre projet est construit en mode Release. Si vous utilisez une ou plusieurs des constantes mathématiques dans un projet incluant également ATLComTime.h, vous devez définir _USE_MATH_DEFINES avant d'inclure ATLComTime.h.

Fichier ATLComTime.h peut être inclus indirectement dans votre projet. Dans mon cas, un ordre d’inclusion possible était le suivant:

projets "stdafx.h"<afxdtctl.h><afxdisp.h><ATLComTime.h><math.h>

0
αλεχολυτ