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
in call to 'f(3)'
- यह अजीब है! पूर्व। यदि आप केf(123)
बारे में चेतावनी देते हैंin call to 'f(119)'
।