মধ্যে পার্থক্য কি
int x=7;
এবং
register int x=7;
?
আমি সি ++ ব্যবহার করছি।
মধ্যে পার্থক্য কি
int x=7;
এবং
register int x=7;
?
আমি সি ++ ব্যবহার করছি।
registerদেওয়াতে সি এবং সি ++ এর মধ্যে বিভিন্ন শব্দার্থক শব্দ রয়েছে।
register int a[1];সেই ঘোষণার সাথে আপনি এই অ্যারেটিকে সূচক করতে পারবেন না। যদি আপনি চেষ্টা করেন তবে আপনি ইউবি করেন
উত্তর:
সি ++ তে এটি ২০১০-তে যেমন বিদ্যমান ছিল, বৈধ যে কোনও প্রোগ্রাম যা কীওয়ার্ডগুলি "অটো" বা "রেজিস্টার" ব্যবহার করে সেগুলি মুছে ফেলা সেই কীওয়ার্ডগুলির সাথে শব্দার্থগতভাবে অভিন্ন হবে (যদি না তারা স্ট্রিংযুক্ত ম্যাক্রো বা অন্যান্য অনুরূপ প্রসঙ্গে উপস্থিত হয়)। সেই অর্থে কীওয়ার্ডগুলি সঠিকভাবে সংকলিত প্রোগ্রামগুলির জন্য অকেজো। অন্যদিকে, ম্যাক্রোর অনুপযুক্ত ব্যবহার বোগাস কোড তৈরির পরিবর্তে একটি সংকলন-সময় ত্রুটির কারণ ঘটবে তা নিশ্চিত করতে নির্দিষ্ট ম্যাক্রো প্রসঙ্গে কীওয়ার্ডগুলি কার্যকর হতে পারে।
ভাষার সি ++ 11 এবং পরবর্তী সংস্করণগুলিতে autoমূলশব্দটি পুনরায় উদ্দিষ্ট বাছাই করা হয়েছিল যা প্রাথমিকভাবে অবজেক্টের জন্য সিউডো-টাইপ হিসাবে কাজ করবে, যা একটি সংকলক স্বয়ংক্রিয়ভাবে আরম্ভের প্রকাশের ধরণের সাথে প্রতিস্থাপন করবে। সুতরাং, সি ++ 03-এ, ঘোষণাটি: কোনও ব্লক প্রসঙ্গে ব্যবহৃত auto int i=(unsigned char)5;হওয়ার সাথে সমান ছিল int i=5;এবং auto i=(unsigned char)5;এটি সীমাবদ্ধ লঙ্ঘন ছিল। সি ++ 11-এ, এর সমতুল্য হয়ে ওঠে auto int i=(unsigned char)5;এবং সীমাবদ্ধতা লঙ্ঘন auto i=(unsigned char)5;হয় auto unsigned char i=5;।
autoসহজেই বাদ দেওয়া যাবে না ... সম্ভবত আপনি নিজের উত্তর আপডেট করতে পারেন।
registerএবং সি ++ 17 এর জন্য এটি অপসারণের প্রস্তাব থাকবে।
autoএখন স্বয়ংক্রিয় টাইপ ছাড়ের জন্য ব্যবহৃত হয় তবে তার আগে এটি নির্দিষ্ট করতে ব্যবহৃত হত যে আপনি নিজের পরিবর্তনশীলটিকে "স্বয়ংক্রিয়ভাবে" সংরক্ষণ করতে চান ( মূলশব্দটির বিপরীতে register(যেমন "প্রসেসরের নিবন্ধ") এর বিপরীতে আমি মনে করি স্ট্যাকের উপরে :
register সংকলকটির একটি ইঙ্গিত, এটি মেমরির পরিবর্তে প্রসেসরের রেজিস্টারে সেই পরিবর্তনশীলটি সংরক্ষণ করার পরামর্শ দেয় (উদাহরণস্বরূপ, স্ট্যাকের পরিবর্তে)।
সংকলকটি সেই ইঙ্গিতটি অনুসরণ করতে পারে বা নাও করতে পারে।
"কীওয়ার্ডগুলি যেগুলি নয় (বা, অন্য নাম দ্বারা মন্তব্য করা হয়েছে)" তে হার্ব সাটারের মতে :
একজন নিবন্ধকার নির্দিষ্টকরণকারীর একটি অটো স্পেসিফায়ারের মতো একই শব্দার্থবিজ্ঞান রয়েছে ...
storage-class-specifierব্যাকরণের কোনও একটি নয় এবং এর কোনও সংজ্ঞায়িত শব্দার্থবিজ্ঞান নেই। একটি মেনে চলার সংকলক ক্ল্যাংয়ের মতো ত্রুটি ফেলে দিতে পারে। তবুও কিছু বাস্তবায়ন এখনও এটিকে অনুমতি দেয় এবং হয় এটিকে (এমএসভিসি, আইসিসি) উপেক্ষা করে বা এটি একটি অপ্টিমাইজেশন ইঙ্গিত (জিসিসি) হিসাবে ব্যবহার করে। ওপেন- std.org/jtc1/sc22/wg21/docs/papers/2015/p0001r1.html দেখুন । যদিও আমি এক পর্যায়ে ভুল বানান করেছি: এটি সি ++ 11 এ অবচয় করা হয়েছিল।
হার্ব সাটারের মতে , register" হোয়াইটস্পেসের মতো হুবহু অর্থপূর্ণ " এবং এটি সি ++ প্রোগ্রামের শব্দার্থবিজ্ঞানের উপর কোনও প্রভাব ফেলে না।
প্রায় অবশ্যই কিছুই।
registerসংকলকটির একটি ইঙ্গিত যা আপনি xপ্রচুর ব্যবহারের পরিকল্পনা করছেন এবং এটি মনে হয় এটি একটি রেজিস্টারে রাখা উচিত।
তবে, কম্পাইলাররা গড় (বা এমনকি বিশেষজ্ঞ) প্রোগ্রামারের তুলনায় রেজিস্টারে কী মান স্থাপন করা উচিত তা নির্ধারণে এখন আরও ভাল, সুতরাং সংকলকগণ কেবল কীওয়ার্ডটিকে উপেক্ষা করে এবং তারা যা চান তা করেন।
registerসি ++ 11 এ অবচয় করা হয়েছে। এটি অব্যবহৃত এবং সি ++ 17 এ সংরক্ষিত।
registerশব্দ জন্য দরকারী ছিল:
একটি উত্পাদনশীল সিস্টেমের উদাহরণ, যেখানে registerকীওয়ার্ডটির প্রয়োজন ছিল:
typedef unsigned long long Out;
volatile Out out,tmp;
Out register rax asm("rax");
asm volatile("rdtsc":"=A"(rax));
out=out*tmp+rax;
এটি C ++ 11 সাল থেকে অবহেলা করা হয়েছে এবং অব্যবহৃত এবং সি ++ 17 এ সংরক্ষিত রয়েছে ।
registerস্টোরেজ ক্লাস নির্দিষ্টকারীর চেয়ে আলাদা এবং এখনও জিসিসি সমর্থন করে।
জিসিসি 9.3 পর্যন্ত ব্যবহার সংকলন -std=c++2a, register একটি কম্পাইলার সতর্কবার্তা উৎপন্ন, কিন্তু এটি এখনও সি এর অভিন্নরুপে আকাঙ্ক্ষিত ফল এবং আচরণ করবে হয়েছে registerOfast অপ্টিমাইজেশান পতাকার সম্মান - যখন -O1 ছাড়া সংকলন এই উত্তর। ঝাঁকুনি ++ - 7 ব্যবহারের কারণে তবে একটি সংকলক ত্রুটির কারণ। হ্যাঁ, registerঅপ্টিমাইজেশানগুলি কোনও অপ্টিমাইজেশন-ও পতাকা সহ স্ট্যান্ডার্ড সংকলনটিতে কেবল একটি পার্থক্য রাখে, তবে সেগুলি বেসিক অপটিমেশান যা সংকলকটি -O1 এর সাথেও খুঁজে পাবে।
পার্থক্যটি হ'ল সি ++ এ, আপনাকে রেজিস্টার ভেরিয়েবলের ঠিকানা নেওয়ার অনুমতি দেওয়া হয়েছে যার অর্থ আপনি কেবলমাত্র ভেরিয়েবলের ঠিকানা না নিয়ে বা এর এলিয়াসগুলি (পয়েন্টার তৈরি করতে) বা রেফারেন্স না নিলে অপ্টিমাইজেশনটি ঘটে কোডটিতে এটির মধ্যে (কেবলমাত্র - O0, কারণ একটি রেফারেন্সেরও একটি ঠিকানা রয়েছে, কারণ এটি স্ট্যাকের একটি কনস্ট পয়েন্টার , যা পয়েন্টারের মতো স্ট্যাকের বাইরে অপ্টিমাইজ করা যেতে পারে -অফেষ্ট ব্যবহার করে সংকলন করা ছাড়া, তারা কখনই উপস্থিত হবে না স্ট্যাকের উপর -অফস্ট ব্যবহার করুন, কারণ পয়েন্টারের বিপরীতে এগুলি তৈরি করা যায় না volatileএবং তাদের ঠিকানাগুলি নেওয়া যায় না), অন্যথায় এটি আপনার ব্যবহার না করার মতো আচরণ registerকরবে এবং স্ট্যাকের মধ্যে মানটি সংরক্ষণ করা হবে।
ও -0-তে, আরেকটি পার্থক্য হ'ল জিসিসি const registerসি এবং জিসিসি সি ++ তে একই আচরণ করে না। জিসিসি সি-তে, এর const registerমতো আচরণ করে registerকারণ ব্লক-স্কোপ constগুলি জিসিসিতে অনুকূলিত হয় না। ঝাঁকুনি সি তে, registerকিছুই করে না এবং কেবলমাত্র constব্লক-স্কোপ অপটিমাইজেশন প্রয়োগ হয়। registerজিসিসি সি তে, অপ্টিমাইজেশন প্রয়োগ হয় তবে constব্লক-স্কোপে কোনও অপ্টিমাইজেশন নেই। জিসিসি সি ++ এ, উভয় registerএবং constব্লক-স্কোপ অপটিমাইজেশন একত্রিত।
#include <stdio.h> //yes it's C code on C++
int main(void) {
const register int i = 3;
printf("%d", i);
return 0;
}
int i = 3;:
.LC0:
.string "%d"
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], 3
mov eax, DWORD PTR [rbp-4]
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
leave
ret
register int i = 3;:
.LC0:
.string "%d"
main:
push rbp
mov rbp, rsp
push rbx
sub rsp, 8
mov ebx, 3
mov esi, ebx
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
mov rbx, QWORD PTR [rbp-8] //callee restoration
leave
ret
const int i = 3;
.LC0:
.string "%d"
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], 3 //still saves to stack
mov esi, 3 //immediate substitution
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
leave
ret
const register int i = 3;
.LC0:
.string "%d"
main:
push rbp
mov rbp, rsp
mov esi, 3 //loads straight into esi saving rbx push/pop and extra indirection (because C++ block-scope const is always substituted immediately into the instruction)
mov edi, OFFSET FLAT:.LC0 // can't optimise away because printf only takes const char*
mov eax, 0 //zeroed: https://stackoverflow.com/a/6212755/7194773
call printf
mov eax, 0 //default return value of main is 0
pop rbp //nothing else pushed to stack -- more efficient than leave (rsp == rbp already)
ret
registerসংস্থাপককে 1 কে বলে) একটি স্থানীয় সঞ্চয়ী ক্যালি সেভ করা রেজিস্টারে সংরক্ষণ করুন rbx, এবং 2) ভেরিয়েবলের ঠিকানা নেওয়া না হলে স্ট্যাক লেখার অনুকূলতা তৈরি করে । constসংকলকটিকে অবিলম্বে মানটির পরিবর্তে (এটি কোনও রেজিস্টার নির্ধারণের পরিবর্তে বা মেমরি থেকে লোড করার পরিবর্তে) পরিবর্তনের জন্য এবং স্থানীয় ভেরিয়েবলটিকে স্ট্যাকের ডিফল্ট আচরণ হিসাবে লিখতে বলে। const registerএই উত্সাহিত অপটিমাইজেশনের সংমিশ্রণ। এটি যতটা পাতলা হয় ততটাই পাতলা।
এছাড়াও, জিসিসি সি এবং সি ++ এ, registerনিজের থেকে স্ট্যাকের প্রথম স্থানীয় লোকের জন্য স্ট্যাকের মধ্যে একটি এলোমেলো 16 বাইট ফাঁক তৈরি করে বলে মনে হচ্ছে যা এর সাথে ঘটে না const register।
-ওফেষ্ট ব্যবহার করে সংকলন; register০ টি অপ্টিমাইজেশান প্রভাব রয়েছে কারণ এটি যদি একটি রেজিস্টারে রাখা বা তাত্ক্ষণিকভাবে তৈরি করা যায় তবে এটি সর্বদা থাকবে এবং যদি তা নাও হয়; constএখনও সি এবং সি ++ এ লোডটি অপ্টিমাইজ করে তবে কেবল ফাইল স্কোপে ; volatileএখনও মানগুলি স্ট্যাক থেকে সংরক্ষণ এবং লোড করতে বাধ্য করে।
.LC0:
.string "%d"
main:
//optimises out push and change of rbp
sub rsp, 8 //https://stackoverflow.com/a/40344912/7194773
mov esi, 3
mov edi, OFFSET FLAT:.LC0
xor eax, eax //xor 2 bytes vs 5 for mov eax, 0
call printf
xor eax, eax
add rsp, 8
ret
একটি ক্ষেত্রে বিবেচনা করুন যখন সংকলকটির অপ্টিমাইজারটিতে দুটি ভেরিয়েবল থাকে এবং একটি স্ট্যাকের মধ্যে ছড়িয়ে দিতে বাধ্য হয়। এটি ঘটেছে যে উভয় ভেরিয়েবলের কম্পাইলারের সমান ওজন রয়েছে। কোনও পার্থক্য দেওয়া নেই, সংকলক যথেচ্ছভাবে একটি ভেরিয়েবল ছড়িয়ে দেবে। অন্যদিকে, registerকীওয়ার্ডটি সংকলকটিকে একটি ইঙ্গিত দেয় যা ভেরিয়েবল আরও ঘন ঘন অ্যাক্সেস করা হবে। এটি x86 প্রিফেট নির্দেশের মতো, তবে সংকলক অপ্টিমাইজারের জন্য।
স্পষ্টতই registerইঙ্গিতগুলি ব্যবহারকারীর সরবরাহিত শাখার সম্ভাব্যতার ইঙ্গিতগুলির অনুরূপ, এবং এই সম্ভাব্যতার ইঙ্গিতগুলি থেকে অনুমান করা যায়। সংকলক যদি জেনে থাকে যে কিছু শাখা প্রায়শই নেওয়া হয় তবে এটি শাখার সাথে সম্পর্কিত ভেরিয়েবলগুলি রেজিস্টারে রাখবে। তাই আমি শাখার ইঙ্গিতগুলি সম্পর্কে আরও যত্নশীল হওয়া এবং ভুলে যাওয়ার পরামর্শ দিই register। আদর্শভাবে আপনার প্রোফাইলারটি কোনওভাবেই সংকলকের সাথে যোগাযোগ করা উচিত এবং আপনাকে এই জাতীয় সংক্ষিপ্তসারগুলি সম্পর্কে ভাবনা থেকেও রেহাই দেওয়া উচিত।