एक अस्थायी स्थिरांक के लिए छद्म-विध्वंसक को कॉल करने का वैध सिंटैक्स


9

निम्नलिखित प्रदर्शन कार्यक्रम पर विचार करें।

#include <iostream>

int main()
{
    typedef float T;

    0.f.T::~T();
}

यह कार्यक्रम द्वारा संकलित है Microsoft Visual Studio Community 2019

लेकिन clangऔर gccइस तरह एक त्रुटि जारी करते हैं

prog.cc:7:5: error: unable to find numeric literal operator 'operator""f.T'
    7 |     0.f.T::~T();
      |     ^~~~~

यदि अभिव्यक्ति लिखना है ( 0.f ).T::~T()तो तीनों संकलनकर्ता कार्यक्रम को संकलित करते हैं।

तो एक सवाल उठता है: क्या यह रिकॉर्ड 0.f.T::~T()वाक्यात्मक रूप से वैध है? और यदि नहीं, तो क्या वाक्यात्मक नियम टूट गया है?


1
के बीच एक रिक्ति लाना 0.fऔर .Tदोनों जीसीसी और बजना का कारण बनता है यह स्वीकार करने के लिए ...
क्रिस

1
के रूप में अच्छी तरह से(0.f).T::~T();
सिगरेट

एक साधारण float f = 1.0f.t;संख्यात्मक शाब्दिक के बारे में त्रुटि पैदा करेगा।
1201ProgramAlarm

floatएक अंतर्निहित प्रकार है, इसमें कॉल करने के लिए आपके पास एक विध्वंसक नहीं है। आप मैन्युअल रूप से विध्वंसक कॉलिंग भी कर रहे हैं? प्लेसमेंट-नए क्षेत्र के बाहर, यह एक बड़ा नहीं-नहीं होना चाहिए ।
जेस्पर जुहल

@JesparJuhl एक विध्वंसक नहीं बल्कि एक छद्म विध्वंसक है, मुझे सिर्फ इतना पता है कि यह मौजूद है। टैग जानकारी का एक उदाहरण है (जिसमें विध्वंसक btw के लिए कोई औचित्य नहीं है)
idclev 463035818

जवाबों:


3

संख्यात्मक टोकनों का पार्सिंग काफी कच्चा है, और कई चीजों को अनुमति देता है जो वास्तव में वैध संख्या नहीं हैं। C ++ 98 में, एक "प्रीप्रोसेसिंग नंबर" के लिए व्याकरण, [lex.ppnumber] में पाया जाता है, है

pp-number:
    digit
    . digit
    pp-number digit
    pp-number nondigit
    pp-number e sign
    pp-number E sign
    pp-number .

यहां, एक "नॉनडॉजिट" ऐसा कोई भी चरित्र है जिसका उपयोग अंकों के अलावा एक पहचानकर्ता में किया जा सकता है, और एक "संकेत" या तो + या - है। बाद के मानक एकल उद्धरण (C ++ 14), और प्रपत्र p-, p +, P-, P + (C ++ 17) के अनुक्रम की अनुमति देने के लिए परिभाषा का विस्तार करेंगे।

अपशॉट वह है, जो मानक के किसी भी संस्करण में है, जबकि अंक के साथ शुरू करने के लिए एक प्रीप्रोसेसिंग संख्या की आवश्यकता होती है, या एक अंक के बाद की अवधि, उसके बाद अंकों, अक्षरों और अवधियों का एक मनमाना अनुक्रम हो सकता है। अधिकतम मंक नियम का उपयोग करते हुए, यह निम्नानुसार 0.f.T::~T();टोकन के रूप में आवश्यक है 0.f.T :: ~ T ( ) ;, भले ही 0.f.Tएक वैध संख्यात्मक टोकन नहीं है।

इस प्रकार, कोड वाक्यात्मक रूप से मान्य नहीं है।


दिलचस्प है, वास्तव में [lex.pptoken] में सभ्य समानता के साथ एक उदाहरण है: eel.is/c++draft/lex.pptoken#5
क्रिस

1

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

इसलिए यह एक कंपाइलर बग है क्योंकि यह गैर-पहचानकर्ता अनुक्रम f.Tको पहचानकर्ता के रूप में मान रहा है।

0.एक है आंशिक-निरंतर है, जो एक वैकल्पिक प्रतिपादक द्वारा या तो पालन किया जा सकता है, तो एक उद-प्रत्यय या एक (एक उपयोगकर्ता शाब्दिक परिभाषित के लिए) फ्लोटिंग प्वाइंट-प्रत्यय (में से एक fFlL)। fएक माना जा सकता है उद-suffx रूप में अच्छी तरह है, लेकिन यह है कि किया जाना चाहिए और न UDL के बाद से यह एक और शाब्दिक प्रकार से मेल खाता। व्याकरण में पहचानकर्ता के रूप में एक उद-प्रत्यय को परिभाषित किया गया है।


इसकी व्याख्या उद-प्रत्यय के रूप में क्यों की जाती है?
मास्को से व्लाद

@VladfromMoscow 0.एक आंशिक-स्थिर है । इसका अनुसरण (घातांक सामग्री को छोड़कर) एक ud-प्रत्यय (उपयोगकर्ता परिभाषित शाब्दिक के लिए) या एक फ्लोटिंग-पॉइंट-प्रत्यय (एक में से एक fFlL) किया जा सकता है। fएक माना जा सकता है उद-suffx रूप में अच्छी तरह है, लेकिन यह है कि किया जाना चाहिए और न UDL के बाद से यह एक और शाब्दिक प्रकार से मेल खाता। व्याकरण में पहचानकर्ता के रूप में एक उद-प्रत्यय को परिभाषित किया गया है ।
1201ProgramAlarm

@ 1201ProgramAlarm: जबकि fउद-प्रत्यय के रूप में व्याख्या की जा सकती, f.Tनहीं के रूप में करना चाहिए .पहचानकर्ता में नहीं हो सकता। लेकिन यह है ... मैं संकलक बग कहना होगा, लेकिन यकीन है कि यह अधिक जटिल है।
Jarod42
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.