আমি মনে করি না যে উত্তরগুলির কোনওটিই এটির ঠিক কী পার্শ্ব প্রতিক্রিয়াগুলি, বা প্রকৃতপক্ষে, এটি পরিষ্কার করে দেয়।
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
constexpr
constexpr
একই ফলাফলের জন্য অন্যান্য ক্রিয়াকলাপগুলি ভিতরে থেকেও ফাংশনগুলি কল করা যায়। constexpr
একটি ফাংশন অন ফাংশন সংকলন সময়ে সম্পন্ন করা যায় না যে কোনও কিছু ব্যবহার প্রতিরোধ করে; উদাহরণস্বরূপ, একটি কল <<
উপর অপারেটর std::cout
।
constexpr
ব্লক স্কোপতে একই আচরণ করে যা এটি একটি ত্রুটি তৈরি করে যদি কোনও অ-কনস্টেক্সপ্রাপ্ত ফাংশন দ্বারা আরম্ভ করা হয়; মানটি অবিলম্বে প্রতিস্থাপিত হয়।
শেষ পর্যন্ত, এর মূল উদ্দেশ্যটি সি এর ইনলাইন ফাংশনের মতো তবে এটি কেবল তখন কার্যকর হয় যখন ফাংশনটি ফাইল-স্কোপ ভেরিয়েবলগুলি সূচনা করতে ব্যবহৃত হয় (যা ফাংশনগুলি সি তে করতে পারে না তবে তারা সি ++ এ করতে পারে কারণ এটি ফাইল- এর গতিশীল সূচনা করার অনুমতি দেয় allows স্কোপ ভেরিয়েবল), ফাংশন ব্যতীত লিঙ্কারে কোনও গ্লোবাল / স্থানীয় প্রতীক রফতানি করতে পারে না, এমনকি সি ব্যবহার করে extern/static
যা আপনি ব্যবহার করতে পারেন inline
; ব্লক-স্কোপ ভেরিয়েবল অ্যাসাইনমেন্ট ফাংশনগুলি কেবল constexpr
সি এবং সি ++ ছাড়াই একটি -O1 অপ্টিমাইজেশন ব্যবহার করে ইনলাইন করা যায় ।
constexpr
একটি সংকলন-সময় ধ্রুবক তৈরি করে;const
সহজভাবে মানে যে মান পরিবর্তন করা যায় না।