আমি মনে করি না যে উত্তরগুলির কোনওটিই এটির ঠিক কী পার্শ্ব প্রতিক্রিয়াগুলি, বা প্রকৃতপক্ষে, এটি পরিষ্কার করে দেয়।
constexprএবং constনামস্থান / ফাইল-স্কোপ এ অভিন্ন একটি আক্ষরিক বা অভিব্যক্তি ইনিশিয়ালাইজ হয়; তবে একটি ফাংশন দিয়ে, constকোনও ফাংশন দিয়ে সূচনা করা যেতে পারে তবে constexprএকটি অ-কনসেক্সেক্সপ্র দ্বারা সূচনা করা হয় (একটি ফাংশন যা কনস্টেক্সপ্র বা একটি কনস্টেক্সপ্র এক্সপ্রেশন দিয়ে চিহ্নিত নয়) সংকলক ত্রুটি তৈরি করবে। উভয় constexprএবং constভেরিয়েবলের জন্য স্পষ্টভাবে অভ্যন্তরীণ লিঙ্কেজ (ভাল আসলে, তারা -O1 এবং শক্তিশালী সংকলন করে লিঙ্কিং পর্যায়ে পৌঁছাতে বাঁচতে staticপারে না এবং সংকলকটিকে অভ্যন্তরীণ (স্থানীয়) লিংক প্রতীক নির্গত করতে constবা constexprকখন সংঘবদ্ধ করতে বাধ্য করে না -O1 বা আরও শক্তিশালী; কেবলমাত্র তখনই এটি করা হয় যদি আপনি ভেরিয়েবলের ঠিকানাটি নেন constএবং constexprএটি প্রকাশ না করে অভ্যন্তরীণ প্রতীক হয়ে থাকবেনextern অর্থাতextern constexpr/const int i = 3;ব্যবহার করা প্রয়োজন)। কোনও ফাংশনে, constexprফাংশনটি স্থায়ীভাবে কখনও লিঙ্কিং পর্যায়ে পৌঁছায় না (নির্বিশেষে externবা inlineসংজ্ঞা বা -O0 বা -Of বাছাই constনা করে ), যেখানে কখনও হয় না staticএবং inlineকেবল ও -1 এবং উপরে এটির প্রভাব থাকে। একটি যখন const/ constexprপরিবর্তনশীল একটি দ্বারা ইনিশিয়ালাইজ করা হয় constexprফাংশন, লোড সবসময় কোনো অপ্টিমাইজেশান পতাকা দিয়ে আউট অপ্টিমাইজ করা হয়, কিন্তু এটি আউট অপ্টিমাইজ করা হয় না যদি ফাংশন শুধুমাত্র staticবা inline, অথবা যদি পরিবর্তনশীল একটি নয় const/ constexpr।
স্ট্যান্ডার্ড সংকলন (-O0)
#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রানটাইম এ।
-অফেষ্ট ব্যবহার করে সংকলন
এমনকি - হালকা লোডটি অপ্টিমাইজ করে না! https://godbolt.org/z/r-mhif , তাই আপনার প্রয়োজন constexpr
constexprconstexprএকই ফলাফলের জন্য অন্যান্য ক্রিয়াকলাপগুলি ভিতরে থেকেও ফাংশনগুলি কল করা যায়। constexprএকটি ফাংশন অন ফাংশন সংকলন সময়ে সম্পন্ন করা যায় না যে কোনও কিছু ব্যবহার প্রতিরোধ করে; উদাহরণস্বরূপ, একটি কল <<উপর অপারেটর std::cout।
constexprব্লক স্কোপতে একই আচরণ করে যা এটি একটি ত্রুটি তৈরি করে যদি কোনও অ-কনস্টেক্সপ্রাপ্ত ফাংশন দ্বারা আরম্ভ করা হয়; মানটি অবিলম্বে প্রতিস্থাপিত হয়।
শেষ পর্যন্ত, এর মূল উদ্দেশ্যটি সি এর ইনলাইন ফাংশনের মতো তবে এটি কেবল তখন কার্যকর হয় যখন ফাংশনটি ফাইল-স্কোপ ভেরিয়েবলগুলি সূচনা করতে ব্যবহৃত হয় (যা ফাংশনগুলি সি তে করতে পারে না তবে তারা সি ++ এ করতে পারে কারণ এটি ফাইল- এর গতিশীল সূচনা করার অনুমতি দেয় allows স্কোপ ভেরিয়েবল), ফাংশন ব্যতীত লিঙ্কারে কোনও গ্লোবাল / স্থানীয় প্রতীক রফতানি করতে পারে না, এমনকি সি ব্যবহার করে extern/staticযা আপনি ব্যবহার করতে পারেন inline; ব্লক-স্কোপ ভেরিয়েবল অ্যাসাইনমেন্ট ফাংশনগুলি কেবল constexprসি এবং সি ++ ছাড়াই একটি -O1 অপ্টিমাইজেশন ব্যবহার করে ইনলাইন করা যায় ।
constexprএকটি সংকলন-সময় ধ্রুবক তৈরি করে;constসহজভাবে মানে যে মান পরিবর্তন করা যায় না।