मुझे नहीं लगता कि कोई भी उत्तर वास्तव में यह स्पष्ट करता है कि इसके क्या दुष्प्रभाव हैं, या वास्तव में, यह क्या है।
constexpr
और const
नाम-स्थान / फ़ाइल-स्कोप समान है जब एक शाब्दिक या अभिव्यक्ति के साथ आरंभ किया जाता है; लेकिन एक फ़ंक्शन के साथ, const
किसी भी फ़ंक्शन द्वारा आरंभीकृत किया जा सकता है, लेकिन constexpr
एक गैर-कॉन्स्ट्रेक्प (एक फ़ंक्शन जिसे कॉन्स्टैक्स या एक गैर कॉन्स्ट्रेक्स अभिव्यक्ति के साथ चिह्नित नहीं किया गया है) द्वारा संकलित किया जाता है। दोनों constexpr
और const
चर के लिए परोक्ष आंतरिक संबंध हैं (अच्छी तरह से वास्तव में, वे अगर -O1 और मजबूत संकलन जोड़ने चरण के लिए प्राप्त करने के लिए जीवित नहीं है, और static
के लिए एक आंतरिक (स्थानीय) लिंकर प्रतीक फेंकना संकलक मजबूर नहीं करता है const
या constexpr
जब पर -O1 या मजबूत, केवल समय यह ऐसा करता है, तो आप चर का पता लेते हैं। const
और constexpr
जब तक साथ व्यक्त एक आंतरिक प्रतीक हो जाएगा extern
यानीextern constexpr/const int i = 3;
उपयोग करने की आवश्यकता है)। एक समारोह को constexpr
बनाता समारोह स्थायी रूप से जोड़ने के स्तर तक पहुंच कभी नहीं (की परवाह किए बिना extern
या inline
परिभाषा या -O0 या -Ofast में), जबकि const
कभी नहीं करता है, और static
और inline
केवल -O1 और इसके बाद के संस्करण पर इस प्रभाव है। जब किसी फ़ंक्शन द्वारा const
/ constexpr
वैरिएबल को इनिशियलाइज़ किया जाता है constexpr
, तो लोड को हमेशा किसी ऑप्टिमाइज़ेशन फ़्लैग के साथ ऑप्टिमाइज़ किया जाता है, लेकिन यह कभी भी ऑप्टिमाइज़ नहीं किया जाता है यदि फ़ंक्शन केवल static
या है inline
, या यदि वैरिएबल ए const
/ नहीं है constexpr
।
मानक संकलन (-ओ 0)
#include<iostream>
constexpr int multiply (int x, int y)
{
return x * y;
}
extern const int val = multiply(10,10);
int main () {
std::cout << val;
}
के लिए संकलित करता है
val:
.long 100 //extra external definition supplied due to extern
main:
push rbp
mov rbp, rsp
mov esi, 100 //substituted in as an immediate
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov eax, 0
pop rbp
ret
__static_initialization_and_destruction_0(int, int):
.
.
.
तथापि
#include<iostream>
const int multiply (int x, int y)
{
return x * y;
}
const int val = multiply(10,10); //constexpr is an error
int main () {
std::cout << val;
}
को संकलित करता है
multiply(int, int):
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov DWORD PTR [rbp-8], esi
mov eax, DWORD PTR [rbp-4]
imul eax, DWORD PTR [rbp-8]
pop rbp
ret
main:
push rbp
mov rbp, rsp
mov eax, DWORD PTR val[rip]
mov esi, eax
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov eax, 0
pop rbp
ret
__static_initialization_and_destruction_0(int, int):
.
.
.
mov esi, 10
mov edi, 10
call multiply(int, int)
mov DWORD PTR val[rip], eax
यह स्पष्ट रूप से पता चलता है कि constexpr
की initialisation का कारण बनता है const/constexpr
फ़ाइल-गुंजाइश चर संकलन समय पर पाए जाते हैं और कोई वैश्विक चिह्न देने में है, जबकि का उपयोग नहीं यह पहले होने की initialisation का कारण बनता है main
रनटाइम पर।
संकलन का उपयोग कर -OIFT
यहां तक कि -Oxt लोड का अनुकूलन नहीं करता है! https://godbolt.org/z/r-mhif , इसलिए आपको चाहिए constexpr
constexpr
constexpr
समान परिणाम के लिए कार्यों को अन्य कार्यों के अंदर से भी बुलाया जा सकता है । constexpr
एक समारोह में भी कुछ भी है कि समारोह में संकलन समय पर नहीं किया जा सकता के उपयोग को रोकता है; उदाहरण के लिए, <<
ऑपरेटर को कॉल करना std::cout
।
constexpr
ब्लॉक स्कोप में उसी तरह का व्यवहार किया जाता है, अगर वह एक गैर-कॉन्स्ट्रेक्स फ़ंक्शन द्वारा आरंभीकृत किया जाता है; मूल्य भी तुरंत प्रतिस्थापित किया जाता है।
अंत में, इसका मुख्य उद्देश्य सी के इनलाइन फ़ंक्शन की तरह है, लेकिन यह केवल तभी प्रभावी होता है जब फ़ंक्शन का उपयोग फ़ाइल-स्कोप वैरिएबल को इनिशियलाइज़ करने के लिए किया जाता है (जो फ़ंक्शंस C पर नहीं कर सकते, लेकिन वे C ++ पर कर सकते हैं क्योंकि यह फ़ाइल के डायनामिक इनिशियलाइज़ेशन की अनुमति देता है) स्कोप वैरिएबल), फ़ंक्शन को छोड़कर लिंकर के लिए एक वैश्विक / स्थानीय प्रतीक निर्यात नहीं कर सकता है, यहां तक कि उपयोग करना extern/static
, जिसे आप inline
सी पर कर सकते हैं ; ब्लॉक-स्कोप वैरिएबल असाइनमेंट फ़ंक्शंस constexpr
को C और C ++ के बिना -O1 ऑप्टिमाइज़ेशन का उपयोग करके केवल इनलाइन किया जा सकता है ।
constexpr
एक संकलन-समय स्थिर बनाता है;const
बस इसका मतलब है कि मूल्य नहीं बदला जा सकता है।