एक कास्टेवल फ़ंक्शन अपरिभाषित व्यवहार की अनुमति क्यों देता है?


16

C ++ में निरंतर अभिव्यक्तियों की बहुत साफ-सुथरी संपत्ति है: उनके मूल्यांकन में अपरिभाषित व्यवहार नहीं हो सकता है ( 7.7.4.7 ):

एक अभिव्यक्ति ई एक मूल स्थिर अभिव्यक्ति है जब तक कि ई का मूल्यांकन, अमूर्त मशीन ([intro.execution]) के नियमों का पालन करता है, निम्न में से एक का मूल्यांकन करेगा:

  • ...

  • एक ऑपरेशन जिसमें इस दस्तावेज़ के [cpp] के माध्यम से [परिचय] में निर्दिष्ट अपरिभाषित व्यवहार होगा [नोट: उदाहरण के लिए, पूर्णांक अतिप्रवाह ([expr.prop]), कुछ सूचक अंकगणित ([expr.add]), सहित। शून्य से विभाजन, या कुछ बदलाव संचालन - अंत नोट];

का मान संग्रहीत करने के लिए कोशिश कर रहा 13!एक में constexpr intवास्तव में एक अच्छा संकलन त्रुटि पैदावार :

constexpr int f(int n) 
{
    int r = n--;
    for (; n > 1; --n) r *= n;
    return r;
}

int main() 
{
    constexpr int x = f(13);
    return x;
}

आउटपुट:

9:19: error: constexpr variable 'x' must be initialized by a constant expression
    constexpr int x = f(13);
                  ^   ~~~~~
4:26: note: value 3113510400 is outside the range of representable values of type 'int'
    for (; n > 1; --n) r *= n;
                         ^
9:23: note: in call to 'f(3)'
    constexpr int x = f(13);
                      ^
1 error generated.

(बीटीडब्लू त्रुटि "एफ (3) 'के लिए कॉल क्यों कहता है", जबकि यह एफ (13) के लिए कॉल है?)

फिर, मैं हटाने constexprसे xहै, लेकिन बनाने के fएक constevalडॉक्स के अनुसार :

कॉन्स्टेवल - निर्दिष्ट करता है कि एक फ़ंक्शन एक तत्काल फ़ंक्शन है, अर्थात फ़ंक्शन के लिए प्रत्येक कॉल को एक संकलन-समय निरंतर का उत्पादन करना चाहिए

मुझे उम्मीद है कि इस तरह के कार्यक्रम से फिर से एक त्रुटि हो जाएगी। लेकिन इसके बजाय, कार्यक्रम यूबी के साथ संकलित और चलता है

ऐसा क्यों है?

UPD: टिप्पणीकारों ने सुझाव दिया कि यह एक कंपाइलर बग है। मैंने इसकी सूचना दी: https://bugs.llvm.org/show_bug.cgi?id=43714


2
in call to 'f(3)'- यह अजीब है! पूर्व। यदि आप के f(123)बारे में चेतावनी देते हैं in call to 'f(119)'
कामिलुक

मुझे लगता है कि यह सिर्फ एक बग है। मानक स्पष्ट है कि "एक तत्काल आह्वान एक निरंतर अभिव्यक्ति होगी"। हालाँकि, यह भी संभव है कि कुछ और जटिल चल रहा हो (यानी, शायद यह आवश्यकता दूर होने वाली है और क्लैंग नए व्यवहार को लागू कर रहा है)।
ब्रायन

3
कंपाइलर बग। यहाँ देखने के लिए कुछ भी नहीं है, आगे चलो।
टीसी

1
@JesperJuhl ने किया।
मिखाइल

4
@StoryTeller Integers दो के पूरक हैं, लेकिन अतिप्रवाह अभी भी अपरिभाषित है।
बैरी

जवाबों:


2

यह एक कंपाइलर बग है। या, अधिक सटीक होने के लिए, यह एक "अंडरइम्प्लीमेंटेड" फीचर है (बगज़िला में टिप्पणी देखें )

युप - लगता है कि कॉन्स्टेवल अभी तक लागू नहीं हुआ है: https://clang.llvm.org/cxx_statusus.html के अनुसार

(कीवर्ड शायद जोड़ा गया है लेकिन वास्तविक कार्यान्वयन समर्थन नहीं है)

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