M_PI math.h के साथ काम करता है लेकिन Visual Studio में cmath के साथ नहीं


94

मैं 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 का उपयोग करता हूं? यदि हाँ, तो मैं इसे कैसे काम कर सकता हूँ?

अद्यतन : अगर मैं GUI में _USE_MATH_DEFINES परिभाषित करता हूं, तो यह काम करता है। कोई सुराग क्यों ऐसा हो रहा है?


क्या आपकी स्रोत फाइलें .c या .cpp हैं?
स्विस

1
स्विस: यहाँ बात नहीं करनी चाहिए।
रुबेंव जूल

बहुत अजीब ... मैं पुष्टि कर सकता हूं कि मुझे वीएस2010 के साथ एक ही मुद्दा मिल रहा है ... मैं देख रहा हूं कि परिभाषित होने से क्या रोक रहा है ... यह कहीं न कहीं अपरिहार्य होना चाहिए ... लेकिन मैं यह पता नहीं लगा सकता हूं कि
Goz

X86 के साथ, यह C2065 त्रुटि की शिकायत करेगा। X64 के साथ, तब कोई त्रुटि नहीं है।
user2616989

जवाबों:


116

दिलचस्प बात यह है कि मैंने इसे एक ऐप पर चेक किया और मुझे वही त्रुटि मिली।

मैंने हेडर के माध्यम से जाँच करने में कुछ समय बिताया कि यह देखने के लिए कि क्या कुछ अपरिभाषित था _USE_MATH_DEFINESऔर कुछ नहीं मिला।

तो मैं चला गया

#define _USE_MATH_DEFINES
#include <cmath>

मेरी फ़ाइल में पहली चीज़ होना (मैं पीसीएच का उपयोग नहीं करता हूं, यदि आप हैं तो आपके पास यह होना चाहिए #include "stdafx.h") और अचानक यह पूरी तरह से संकलित हो जाता है।

इसे पृष्ठ पर ऊपर ले जाने का प्रयास करें। पूरी तरह से अनिश्चित है कि क्यों यह हालांकि मुद्दों का कारण होगा।

संपादित करें : यह पता लगाया। #include <math.h>Cmath के हेडर गार्ड के भीतर होती है। इसका मतलब यह है कि #includes की सूची में कुछ ऊपर निर्दिष्ट cmathकिए बिना शामिल है #definemath.hको विशेष रूप से डिज़ाइन किया गया है ताकि आप इसे फिर से शामिल कर सकें कि परिभाषित अब बदल गया है M_PIआदि को जोड़ने के लिए यह ऐसा नहीं है cmath। इसलिए आपको #define _USE_MATH_DEFINESकुछ और शामिल करने से पहले यह सुनिश्चित करने की आवश्यकता है। आशा है कि आप के लिए इसे साफ करता है :)

असफल होना, जिसमें math.hआप शामिल हैं, आप गैर-मानक C / C ++ का उपयोग कर रहे हैं जैसा कि पहले ही बताया गया है :)

संपादित करें 2 : या जैसा कि डेविड ने टिप्पणी में बताया है कि अपने आप को एक निरंतर बनाइए जो मूल्य को परिभाषित करता है और आपके पास वैसे भी कुछ अधिक पोर्टेबल है :)


इससे पहले stdafx.hकि यह ओपी समस्या मैं इस व्यवहार का सामना किया है पहले परिभाषित किया गया है।
आलोक सेव

@ आल्स: नॉट इट्स नॉट ... ने इसे क्रैक किया है और ऊपर मेरे एडिट में समझाया गया है :)
Goz

खैर यह पहली बात थी, इसे अन्य सभी चरणों से ऊपर रखें, मैंने ओपी को ऐसा करने के लिए कहा था। किसी भी तरह से मेरा उत्तर हटा दिया जाएगा क्योंकि आपका जवाब कहता है कि यह मानक हेडर से पहले क्यों होना चाहिए।
आलोक सेव

3
आप इस व्यवहार को प्राप्त करेंगे, उदाहरण के लिए, यदि आपके करने से पहले कुछ और #include <math.h> हुआ। उस ने कहा, मानक में ऐसा कुछ भी नहीं है जो कहता है कि <cmath> में <math.h> को शामिल करना है, या इसे <math.h> में गैर-मानक परिभाषाओं को सक्षम करना है। दुर्भाग्य से, M_PI गैर-मानक है। पोर्टेबिलिटी के लिए, सबसे अच्छी बात यह है कि इसे स्वयं परिभाषित करें। बेहतर अभी तक, यह एक # const static doubleमूल्य के बजाय एक अच्छा मूल्य बनाते हैं ।
डेविड हैमेन

1
@ डेविड हैमेन: सहमत .. इसे परिभाषित करना निश्चित रूप से सबसे पोर्टेबल विकल्प है :)
Goz

14

स्विच / D_USE_MATH_DEFINES को अपनी संकलन कमांड लाइन में जोड़ने पर विचार करें, या प्रोजेक्ट सेटिंग्स में मैक्रो को परिभाषित करने के लिए। यह शामिल करने के स्रोत और स्रोत फ़ाइलों को कई प्लेटफार्मों के लिए अपने स्रोत को साफ करने के लिए सभी पहुंच वाले अंधेरे कोनों पर प्रतीक को खींच देगा। यदि आप इसे पूरी परियोजना के लिए विश्व स्तर पर सेट करते हैं, तो आप इसे बाद में एक नई फ़ाइल (एस) में नहीं भूलेंगे।


VisualStudio से काम करते समय शायद यह एक अच्छा जवाब है, लेकिन ध्यान दें कि जब मैटलैब मैक्सिको कमांड लाइन (मैंने इस्तेमाल किया था mex -D_USE_MATH_DEFINES) को संकलित करते समय मेरे लिए यह समस्या हल नहीं हुई थी । केवल /Y-कुछ मटैलैब मेसोप्टेशन फाइल में स्माइली को जोड़ने से मदद मिली ...
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:।

आपके द्वारा पोस्ट किए गए कोड में एक बेमेल होना चाहिए और जिसे आप संकलित करने का प्रयास कर रहे हैं।

सुनिश्चित करें कि आपके सामने किसी भी प्रकार के पूर्वनिर्धारित हेडर नहीं खींचे जा रहे हैं #define


VisualStudio का आप किस संस्करण का उपयोग कर रहे हैं?
गोज

विजुअल C ++ 2010 एक्सप्रेस एडिशन के कमांड लाइन कंपाइलर का उपयोग करके उसी कार्यक्रम ने मेरे लिए ठीक काम किया। अंतर केवल इतना है कि मैंने std :: printf () <cstdio> के बजाय std :: cout का उपयोग <iostream> से किया है।

4
हाँ, मुझे यह समझ में आया ... क्योंकि मैथ्स को सेमीथ के हेडर गार्ड के भीतर से बुलाया जाता है ... इसलिए मैथ्स को पहले ही हेडर से #define सेट के बिना शामिल कर लिया गया है :)
Goz

4

यह अभी भी वीएस कम्युनिटी 2015 और 2017 में एक मुद्दा है जब या तो कंसोल या विंडोज़ ऐप का निर्माण किया जाता है। यदि प्रोजेक्ट पूर्व-निर्मित हेडर के साथ बनाया गया है, तो precompiled हेडर स्पष्ट रूप से किसी भी #includes से पहले लोड किए जाते हैं , इसलिए भले ही #define _USE_MATH_DEFINES पहली पंक्ति हो, यह संकलित होगा। # गणित को सीताथ के बजाय अलग करने से कोई फर्क नहीं पड़ता।

एकमात्र समाधान जो मैं पा सकता हूं, वे या तो एक खाली परियोजना (सरल कंसोल या एम्बेडेड सिस्टम ऐप के लिए) से शुरू करने के लिए या कमांड लाइन के तर्कों को जोड़ने के लिए / वाई- हैं, जो पूर्व-निर्मित हेडर के लोडिंग को बंद कर देता है।

पूर्वनिर्धारित हेडर अक्षम करने की जानकारी के लिए, उदाहरण के लिए https://msdn.microsoft.com/en-us/library/1hy7a92h.aspx देखें

यह अच्छा होगा यदि एमएस इसे बदल देगा / ठीक कर देगा। मैं एक बड़े विश्वविद्यालय में परिचयात्मक प्रोग्रामिंग पाठ्यक्रम पढ़ाता हूं, और जब तक वे गलती नहीं करते हैं और एक दोपहर या तो इसके लिए संघर्ष करते हैं, तब तक यह बताते हुए कि नए लोगों को कभी नहीं डूबता है।


मैं इस बात की पुष्टि करता हूं कि हैकिंग / Y- ने मेरे लिए, C कोड के लिए काम किया #include <math.h>
aka.nice

1
वीएस में यह कोई मुद्दा नहीं है। _USE_MATH_DEFINESकिसी भी हेडर को शामिल करने से पहले परिभाषित किया जाना चाहिए। आमतौर पर या तो प्रोजेक्ट सेटिंग के माध्यम से या कॉन्फ़िगरेशन हेडर के माध्यम से। यह मान लेना गलत है कि इसे पहली पंक्ति में रखने से यह सभी हेडर से पहले परिभाषित हो जाएगा।
user7860670

1

गणित के अनुसार कांस्टेंट कांस्टेंट :

फ़ाइल ATLComTime.hमें math.hतब शामिल होता है जब आपका प्रोजेक्ट रिलीज़ मोड में बनाया जाता है। यदि आप किसी प्रोजेक्ट में एक या एक से अधिक गणित स्थिरांक का उपयोग करते हैं ATLComTime.h, जिसमें आप भी शामिल हैं , तो _USE_MATH_DEFINESआपको शामिल करने से पहले परिभाषित करना होगा ATLComTime.h

फ़ाइल ATLComTime.hको अप्रत्यक्ष रूप से आपकी परियोजना में शामिल किया जा सकता है। मेरे मामले में निम्नलिखित में से एक संभावित आदेश निम्नलिखित था:

प्रोजेक्ट का "stdafx.h"<afxdtctl.h><afxdisp.h><ATLComTime.h><math.h>


यह समझा सकता है कि क्यों / Y- (stdafx.h को अक्षम करें) समस्या का समाधान करेगा, हालांकि यह व्याख्या करना शेष है कि -D_USE_MATH_DEFINESडिफ़ॉल्ट कंपाइलर सेटिंग में प्रदान करने से समस्या को हल करने के लिए पर्याप्त नहीं है ... चूंकि संकलन मैटलैब मैक्सिको कमांड के माध्यम से मेरे लिए था। समस्या, यह ट्रैक करने के लिए स्पष्ट नहीं है ...
aka.nice

0

जैसा कि user7860670 द्वारा सुझाया गया है, प्रोजेक्ट पर राइट-क्लिक करें, गुणों का चयन करें, C / C ++ -> Preprocessor पर नेविगेट करें और _USE_MATH_DEFINESPreprocessor परिभाषाओं में जोड़ें ।

मेरे लिए यही काम आया।


0

CMake के साथ यह सिर्फ होगा

add_compile_definitions(_USE_MATH_DEFINES)

में है CMakeLists.txt

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.