হ্যাঁ, আইএসও সি ++ এই পছন্দটি করার জন্য বাস্তবায়নের অনুমতি দেয় (তবে প্রয়োজন হয় না)।
তবে এও নোট করুন যে আইএসও সি ++ এমন একটি সংকলককে কোড নির্গত করতে দেয় যা উদ্দেশ্য অনুসারে ক্র্যাশ হয় (উদাহরণস্বরূপ একটি অবৈধ নির্দেশ সহ) যদি প্রোগ্রামটি ইউবির মুখোমুখি হয়, যেমন আপনাকে ত্রুটিগুলি খুঁজে পেতে সহায়তা করার উপায় হিসাবে। (বা এটি একটি ডেথস্টেশন 9000 কারণ কোনও কঠোরভাবে মেনে চলা সি ++ বাস্তবায়ন যে কোনও বাস্তব উদ্দেশ্যে কার্যকর হওয়ার জন্য যথেষ্ট নয়)) তাই আইএসও সি ++ কম্পাইলার এ এস এম যে (সম্পূর্ণ ভিন্ন কারণে) ক্র্যাশ এমনকি অনুরূপ কোডটি একটি uninitialized পড়া উপর করার অনুমতি প্রদান করবে uint32_t
। যদিও কোনও ফাঁদের উপস্থাপনা ছাড়াই এটি একটি স্থির-লেআউট প্রকারের হতে হবে।
এটি বাস্তব বাস্তবায়ন কীভাবে কাজ করে সে সম্পর্কে একটি আকর্ষণীয় প্রশ্ন, তবে মনে রাখবেন যে উত্তরটি পৃথক হলেও আপনার কোডটি এখনও নিরাপদ হবে কারণ আধুনিক সি ++ অ্যাসেম্বলি ভাষার কোনও বহনযোগ্য সংস্করণ নয়।
আপনি x86-64 সিস্টেম ভি এবিআইয়ের জন্য সংকলন করছেন , যা উল্লেখ করে যে bool
কোনও রেজিস্টারে ফাংশন আর্গ হিসাবে বিট-প্যাটার্নগুলি false=0
এবংtrue=1
নিবন্ধের 1 এর কম 8 বিটগুলিতে প্রতিনিধিত্ব করা হয় । মেমোরিতে, bool
একটি 1-বাইট প্রকার যা আবার 0 বা 1 এর পূর্ণসংখ্যার মান হওয়া আবশ্যক।
(একটি এবিআই বাস্তবায়ন পছন্দগুলির একটি সেট যা একই প্ল্যাটফর্মের সংকলকরা এতে একমত হয় যাতে তারা কোড তৈরি করতে পারে যা একে অপরের ফাংশনগুলিতে কল করে, টাইপ আকার, কাঠামোর বিন্যাস বিধিবদ্ধকরণ এবং কলিং কনভেনশন সহ including)
আইএসও সি ++ এটি নির্দিষ্ট করে না, তবে এবিআইয়ের এই সিদ্ধান্তটি ব্যাপক কারণ এটি বুল-> ইন রূপান্তরকে সস্তা করে তোলে (কেবল শূন্য-এক্সটেনশন) । আমি এমন কোনও এবিআই সম্পর্কে অবগত নই যা bool
কোনও আর্কিটেকচারের জন্য (কেবল x86 নয়) সংকলককে 0 বা 1 ধরে নিতে দেয় না। মনে হচ্ছে অপ্টিমাইজেশন পারবেন !mybool
সঙ্গে xor eax,1
: কম বিট টুসকি কোন সম্ভাব্য কোডটি 0 এবং 1 এর মধ্যে একটি বিট / পূর্ণসংখ্যা / bool, টুসকি করতে একক CPU- র নির্দেশনা । বা প্রকারের a&&b
জন্য এবং কিছুটা দিকের সংকলন bool
। কিছু সংকলক আসলে 8 বিট হিসাবে সংকলক হিসাবে বুলিয়ান মান গ্রহণ করে । তাদের উপর অপারেশন কি অকার্যকর? ।
সাধারণভাবে, যেমন-নিয়মটি সংকলককে লক্ষ্য প্ল্যাটফর্মের জন্য সত্য যেগুলি সংকলিত হচ্ছে সেগুলির সুবিধা গ্রহণের অনুমতি দেয় , কারণ শেষ ফলাফলটি এক্সিকিউটেবল কোড হবে যা সি ++ উত্সের মতো একই বাহ্যিক-দৃশ্যমান আচরণকে কার্যকর করে। (প্রকৃতপক্ষে "বাহ্যিকভাবে দৃশ্যমান" যা আছে তার উপর অনির্ধারিত আচরণের সমস্ত বিধিনিষেধের সাথে: কোনও ডিবাগার দিয়ে নয়, তবে একটি সুগঠিত / আইনী সি ++ প্রোগ্রামের অন্য থ্রেড থেকে))
সংকলকটি অবশ্যই তার কোড-জেনে কোনও এবিআই গ্যারান্টির পুরো সুবিধা নেওয়ার অনুমতি পেয়েছে এবং আপনার মতো কোড তৈরি করতে strlen(whichString)
পারে যা কোনটি উপযুক্ত করে
5U - boolValue
। (বিটিডাব্লু, এই অপ্টিমাইজেশনটি ধূর্ত চালাক, তবে সম্ভবত সংক্ষিপ্ততর বনাম ব্রাঞ্চিং এবং memcpy
তাত্ক্ষণিক ডেটা 2 হিসাবে স্টোর হিসাবে অন্তর্নিহিত ))
অথবা সংকলকটি পয়েন্টারগুলির একটি সারণী তৈরি করতে পারে এবং bool
আবার এটি 0 বা 1 বলে ধরে নিয়ে এর পূর্ণসংখ্যার মান সহ সূচী তৈরি করতে পারে (( বারমারের উত্তর প্রস্তাবিত এই সম্ভাবনাটিই তাই ))
__attribute((noinline))
অপ্টিমাইজেশান সক্ষম আপনার নির্মাণকারীর ঝাঁকুনির কারণ হিসাবে স্ট্যাক থেকে কেবল একটি বাইট লোড করা হয়েছিল uninitializedBool
। এটা তোলে বস্তুর জন্য স্থান তৈরি main
সঙ্গে push rax
(যা ক্ষুদ্রতর এবং বিভিন্ন কারণে হিসাবে দক্ষ হিসাবে সম্পর্কে sub rsp, 8
), তাই যাই হোক না কেন আবর্জনা এন্ট্রি উপর আওয়ামী লীগের যে অবস্থায় ছিল সেই main
মান জন্য ব্যবহার করা হয় uninitializedBool
। এ কারণেই আপনি আসলে এমন মান পেয়েছেন যা কেবল ছিল না 0
।
5U - random garbage
আনম্যাপযুক্ত মেমরিতে যেতে মেমকিটিকে নেতৃত্ব দিয়ে সহজেই একটি বৃহত স্বাক্ষরিত মানকে মোড়তে পারে। গন্তব্য স্থিতিশীল স্টোরেজে রয়েছে, স্ট্যাক নয়, সুতরাং আপনি কোনও ফেরতের ঠিকানা বা অন্য কোনও বিষয়কে ওভাররাইট করছেন না।
অন্যান্য বাস্তবায়নগুলি বিভিন্ন পছন্দ করতে পারে, যেমন false=0
এবং true=any non-zero value
। তারপরে ঝাঁকুনি সম্ভবত ইউবি- র এই নির্দিষ্ট উদাহরণের জন্য ক্র্যাশ করা কোড তৈরি করবে না । (তবে এটি চাইলে এটি অনুমতি দেওয়া হবে)) x86-64 এর জন্য অন্য কিছু বেছে নেওয়া এমন কোনও বাস্তবায়ন আমার জানা নেই bool
, তবে সি ++ স্ট্যান্ডার্ড এমন অনেক কিছুই মঞ্জুরি দেয় যা কেউ করে না বা এমনকি এটি করতে চায় না হার্ডওয়্যার যা বর্তমানের সিপিইউগুলির মতো কিছু।
আইএসও সি ++ এটিকে কোনও অজানা প্রতিনিধিত্ব পরীক্ষা করে বা সংশোধন করার সময় আপনি কী পাবেন তা অনির্দিষ্ট করে ছেড়ে দেয়bool
। (যেমন দ্বারা memcpy
ing bool
মধ্যে unsigned char
, যা আপনি কারণ করার অনুমতি করছি char*
করতে পারেন ওরফে কিছু। এবং unsigned char
কোনো প্যাডিং বিট আছে নিশ্চিত করা হয়, তাই C ++ স্ট্যান্ডার্ডের আনুষ্ঠানিকভাবে যদি আপনি কোন UB ছাড়া বস্তুর উপস্থাপনা hexdump দিন নেই। বস্তুর অনুলিপি করতে পয়েন্টার ভোটদান প্রতিনিধিত্ব নির্ধারণের চেয়ে আলাদা char foo = my_bool
, অবশ্যই, তাই 0 বা 1 তে বুলিওনাইজেশন ঘটবে না এবং আপনি কাঁচা বস্তুর প্রতিনিধিত্ব পাবেন))
আপনি থাকেন আংশিকভাবে "লুকানো" সঙ্গে কম্পাইলার থেকে এই সঞ্চালনের পথে UBnoinline
। এমনকি যদি এটি ইনলাইন না করে তবে ইন্টারপ্রেসিডুরাল অপটিমাইজেশনগুলি এখনও ফাংশনের একটি সংস্করণ তৈরি করতে পারে যা অন্য ফাংশনের সংজ্ঞা উপর নির্ভর করে। (প্রথমত, ঝাঁকুনি একটি এক্সিকিউটেবল তৈরি করছে, ইউনিক্স শেয়ার্ড লাইব্রেরি নয়, যেখানে প্রতীক-ইন্টারপজেশন ঘটতে পারে। দ্বিতীয়ত, সংজ্ঞাটির অভ্যন্তরে class{}
সংজ্ঞা তাই সমস্ত অনুবাদ ইউনিটগুলির অবশ্যই একই সংজ্ঞা থাকতে হবে। inline
কীওয়ার্ডের মতো ।)
সুতরাং একটি সংকলক সংজ্ঞা হিসাবে কেবল একটি ret
বা ud2
(অবৈধ নির্দেশ) নির্গত করতে পারে main
, কারণ মৃত্যুদণ্ডের পথটি main
অনিবার্যভাবে শুরু হয় অনির্ধারিত আচরণের সাথে। (কোন অন-ইনলাইন কনস্ট্রাক্টরের মাধ্যমে পথটি অনুসরণ করার সিদ্ধান্ত নিলে সংকলকটি সংকলনের সময় দেখতে পাবে))
ইউবির মুখোমুখি হওয়া যে কোনও প্রোগ্রাম তার সম্পূর্ণ অস্তিত্বের জন্য সম্পূর্ণ অপরিজ্ঞাত। কিন্তু এমন কোনও ফাংশন বা if()
শাখার অভ্যন্তরে ইউবি প্রকৃতপক্ষে কখনও চালিত হয় না যা বাকি প্রোগ্রামকে দূষিত করে না। অনুশীলনে এর অর্থ হ'ল সংকলকরা অবৈধ নির্দেশনা নির্বাহের সিদ্ধান্ত নিতে পারে, বা ক ret
, বা কিছু নির্গত করতে না পারে এবং পুরো ব্লক / ফাংশনে পড়তে পারে, সম্পূর্ণ বেসিক ব্লকের জন্য যা সংকলন সময়ে প্রমাণিত হতে পারে যা ইউবির ধারণ করে বা নেতৃত্ব দিতে পারে।
জিসিসি ও অনুশীলন মধ্যে ঝনঝন শব্দ না আসলে কখনও কখনও নির্গত ud2
পরিবর্তে এমনকি মৃত্যুদণ্ড পাথ কোনো অর্থে দেখা যায় কোড জেনারেট করতে চেষ্টা, UB উপর। বা কোনও অ- void
কার্যকারিতা শেষে পড়ে যাওয়ার মতো ক্ষেত্রে , কখনও কখনও জিসিসি কোনও ret
নির্দেশ বাদ দেয় । আপনি যদি ভাবছিলেন যে "আমার ফাংশনটি RAX এ যা কিছু আবর্জনা রয়েছে তা দিয়েই ফিরে আসবে", আপনি খুব খারাপভাবে ভুল হয়ে গেছেন। আধুনিক সি ++ সংকলকরা আর কোনও পোর্টেবল সমাবেশের ভাষার মতো ভাষা ব্যবহার করে না। আপনার কার্যকারিতাটির অবিচ্ছিন্ন অ-ইনলাইনড সংস্করণটি কীভাবে asm এ দেখা যাবে সে সম্পর্কে অনুমান করা ছাড়াই আপনার প্রোগ্রামটি সত্যই বৈধ সি ++ হতে হবে।
আর একটি মজাদার উদাহরণ হ'ল এমএমপিড মেমরিটিতে স্বাক্ষরবিহীন অ্যাক্সেসটি কেন কখনও কখনও এএমডি 64 এ সেগফল্ট করে? । x86 আন-স্বাক্ষরিত পূর্ণসংখ্যার উপর দোষ দেয় না, তাই না? তাহলে কেন ভুল পথে চালিত uint16_t*
সমস্যা হবে? কারণ alignof(uint16_t) == 2
, এবং এই অনুমানের লঙ্ঘন করলে এসএসই 2-এর সাথে স্বয়ংক্রিয়ভাবে ভেক্টরাইজ করার সময় সেগফল্টের দিকে নিয়ে যায়।
আরও দেখুন কি প্রতিটি সি প্রোগ্রামার উচিত জানা অনির্ধারিত আচরণ # 1/3 সম্বন্ধে , একটি ঝনঝন ডেভেলপার দ্বারা একটি নিবন্ধ।
কী পয়েন্ট: যদি কম্পাইলার কম্পাইল সময়ে UB খেয়াল, এটা পারে "বিরতি" আপনার কোড মাধ্যমে (বিস্ময়কর এ এস এম নির্গত) পথ যা কারণ এমনকি একটি ABI- র যেখানে কোনো বিট-প্যাটার্ন জন্য একটি বৈধ বস্তু উপস্থাপনা লক্ষ্য করে যদি UB bool
।
প্রোগ্রামার দ্বারা অনেক ভুলের প্রতি সম্পূর্ণ শত্রুতা প্রত্যাশা করুন, বিশেষত আধুনিক সংকলকরা যে বিষয়গুলি সম্পর্কে সতর্ক করে দিয়েছে। এজন্য আপনার -Wall
সতর্কতা ব্যবহার করা এবং ঠিক করা উচিত । সি ++ কোনও ব্যবহারকারী-বান্ধব ভাষা নয় এবং সি ++ এর কিছু এমন কিছু ক্ষেত্রেও অনিরাপদ হতে পারে যদিও আপনি যে টার্গেটটি সংকলন করছেন তার পক্ষে এটি নিরাপদে থাকবে। (উদাহরণস্বরূপ স্বাক্ষরিত ওভারফ্লো সি ++ এ ইউবি এবং সংকলকরা ধরে নেবে যে 2 এর পরিপূরক x86 এর জন্য সংকলন করার পরেও, আপনি ব্যবহার না করেই clang/gcc -fwrapv
।)
সংকলন-সময়-দৃশ্যমান ইউবি সর্বদা বিপজ্জনক, এবং এটি নিশ্চিত হওয়া সত্যিই কঠিন (লিঙ্ক-টাইম অপ্টিমাইজেশান সহ) যে আপনি সত্যিই সংকলকটি থেকে ইউবি লুকিয়ে রেখেছেন এবং এটি কী ধরণের এএসএম তৈরি করবে সে সম্পর্কে যুক্তিযুক্ত হতে পারে।
অতিরিক্ত নাটকীয় হতে হবে না; প্রায়শই সংকলকগুলি আপনাকে কিছু জিনিস দিয়ে দূরে সরে যায় এবং কোডটি এমিটের মতো সারণী করে দেয় যা আপনি যখন কিছুটা ইউবি হয় তখনও আপনি প্রত্যাশা করেন। তবে ভবিষ্যতে সমস্যা হতে পারে যদি সংকলক কিছু অপ্টিমাইজেশন প্রয়োগ করে যা মান-সীমা সম্পর্কে আরও তথ্য অর্জন করে (যেমন একটি পরিবর্তনশীল অ-নেতিবাচক, সম্ভবত এটি x86- এ শূন্য-এক্সটেনশন মুক্ত সাইন-এক্সটেনশনটিকে অনুকূলিতকরণের অনুমতি দেয়) 64)। উদাহরণস্বরূপ, বর্তমান জিসিসি এবং বিড়ম্বনায়, করা সর্বদা-মিথ্যা হিসাবে tmp = a+INT_MIN
অনুকূলিত হয় না a<0
, কেবল এটি tmp
সর্বদা নেতিবাচক। (কারণ INT_MIN
+ a=INT_MAX
এই 2 এর পরিপূরক টার্গেটের জন্য নেতিবাচক, এবং এর a
চেয়ে বড় কোনওটি হতে পারে না))
সুতরাং জিসিসি / ক্ল্যাং বর্তমানে কোনও গণনার ইনপুটগুলির জন্য পরিসীমা তথ্য পেতে ব্যাকট্র্যাক করবে না, কেবলমাত্র কোনও স্বাক্ষরিত ওভারফ্লো অনুমানের ভিত্তিতে ফলাফলের ভিত্তিতে: গডবোল্টের উপর উদাহরণ । আমি জানি না এটি অপ্টিমাইজেশানটি ব্যবহারকারী-বন্ধুত্বের নামে বা কী কারণে ইচ্ছাকৃতভাবে "মিস" হয়েছে কিনা।
এছাড়াও নোট করুন যে বাস্তবায়নগুলি (ওরফে সংকলক) এমন আচরণের সংজ্ঞা দিতে মঞ্জুরি দেয় যা আইএসও সি ++ অপরিবর্তিত থাকে । উদাহরণ হিসেবে বলা যায়, সব কম্পাইলার যে সমর্থন ইন্টেলের intrinsics (যেমন _mm_add_ps(__m128, __m128)
ম্যানুয়াল SIMD vectorization জন্য) বিরচন ভুল প্রান্তিককৃত পয়েন্টার, যা সি মধ্যে UB হয় ++, এমনকি যদি আপনি অনুমতি প্রদান করা আবশ্যক না তাদের ডি-রেফারেন্স। __m128i _mm_loadu_si128(const __m128i *)
বিভ্রান্তিকর __m128i*
আর্গুমেন্ট গ্রহণ করে স্বাক্ষরবিহীন লোডগুলি করে , একটি void*
বা নয় char*
। হার্ডওয়্যার ভেক্টর পয়েন্টার এবং সংশ্লিষ্ট ধরণের মধ্যে `পুনরায় ব্যাখ্যা_কাস্টিং কি একটি অপরিজ্ঞাত আচরণ?
জিএনইউ সি / সি ++ -fwrapv
সাধারণ স্বাক্ষরিত-ওভারফ্লো ইউবি বিধিগুলি থেকে পৃথক করে বাম-স্থানান্তরিত নেতিবাচক স্বাক্ষরযুক্ত সংখ্যাটি (এমনকি ছাড়াই ) সংজ্ঞা দেয়। ( এটি আইএসও সি ++ এ ইউবি , যখন স্বাক্ষরযুক্ত সংখ্যার ডান শিফটগুলি বাস্তবায়ন-সংজ্ঞায়িত (যৌক্তিক বনাম গাণিতিক); ভাল মানের বাস্তবায়নগুলি এইচডাব্লুটিতে পাটিগণিত চয়ন করে যেখানে পাটিগণিতের ডান শিফট থাকে, তবে আইএসও সি ++ নির্দিষ্ট করে না)। এটি জিসিসি ম্যানুয়ালটির পূর্ণসংখ্যা বিভাগে বাস্তবায়ন-সংজ্ঞায়িত আচরণ সংজ্ঞায়িত করার সাথে সাথে সি মানকগুলির একটি উপায় বা অন্য কোনও সংজ্ঞা দেওয়ার জন্য বাস্তবায়ন প্রয়োজন।
বাস্তবায়িত মানের-বাস্তবায়ন সংক্রান্ত সমস্যাগুলি রয়েছে যা সংকলক বিকাশকারীরা যত্নশীল হন; তারা সাধারণত কম্পাইলারগুলি তৈরি করার চেষ্টা করে না যা ইচ্ছাকৃতভাবে প্রতিকূল হয়, তবে সি ++ এর সমস্ত ইউবি পাথরের (যেগুলি তারা সংজ্ঞায়িত করতে পছন্দ করেন ব্যতীত) আরও ভাল করার জন্য সুবিধা গ্রহণ করা প্রায়শই প্রায় পৃথক হতে পারে।
পাদটীকা 1 : উপরের 56 টি বিট আবর্জনা হতে পারে যা কলিকে অবশ্যই উপেক্ষা করতে হবে, যেমন নিবন্ধের চেয়ে সংকীর্ণ প্রকারের জন্য usual
( অন্য Abis না এখানে বিভিন্ন পছন্দ করতে । কিছু সংকীর্ণ পূর্ণসংখ্যা ধরনের প্রয়োজন না zero- বা সাইন-বাড়ানো একটি রেজিস্টার পূরণ হতে যখন প্রেরণ বা ফাংশন, MIPS64 এবং PowerPC64 মত থেকে ফিরে আসেন। শেষ অধ্যায় দেখুন এই x86-64 'উত্তর যা পূর্ববর্তী আইএসএগুলির তুলনায় বনামের তুলনা করে ))
উদাহরণস্বরূপ, কল করার আগে কলকারী a & 0x01010101
আরডিআইতে গণনা করেছেন এবং এটি অন্য কোনও কিছুর জন্য ব্যবহার করেছেন bool_func(a&1)
। কলার অপ্টিমাইজ করতে পারে &1
কারণ এটি ইতিমধ্যে এর অংশ হিসাবে লো বাইটে and edi, 0x01010101
এটি করেছিল এবং এটি জানে যে উচ্চ বাইটগুলি উপেক্ষা করার জন্য কলি প্রয়োজন।
অথবা যদি কোনও তৃতীয় তর্ক হিসাবে পাস হয়, তবে কোড-সাইজের জন্য অনুকূল একটি কলকারী mov dl, [mem]
তার পরিবর্তে লোড করে movzx edx, [mem]
, আরডিএক্সের পুরানো মান (বা অন্যান্য আংশিক-নিবন্ধের প্রভাবের উপর নির্ভর করে, একটি মিথ্যা নির্ভরতার দামে 1 বাইট সঞ্চয় করে) সিপিইউ মডেলটিতে)। বা mov dil, byte [r10]
পরিবর্তে প্রথম তর্কটির জন্য movzx edi, byte [r10]
, কারণ উভয়ই যাইহোক RX উপসর্গের প্রয়োজন।
এই কেন ঝনঝন নিঃসরণ করে হয় movzx eax, dil
যে Serialize
পরিবর্তে sub eax, edi
। (পূর্ণসংখ্যার উপাখ্যানগুলির জন্য, ক্ল্যাং জিসি-র শিরোনামহীন আচরণের উপর নির্ভর করে শূন্য- অথবা সাইন-প্রসারিত সরু পূর্ণসংখ্যার 32 বিটের উপর নির্ভর করে a২ বিট অফসেটের জন্য পয়েন্টারে সংযুক্ত করার সময় একটি চিহ্ন বা শূন্য এক্সটেনশন প্রয়োজন কি? x86-64 এবিআই?
সুতরাং আমি আগ্রহী যে এটি একই জিনিসটি না করে তা দেখতে আগ্রহী bool
))
পাদটীকা 2: শাখার পরে, আপনি কেবল একটি 4 বাইট- mov
মিমিটেড, বা একটি 4 বাইট + 1-বাইট স্টোর পাবেন। দৈর্ঘ্য স্টোর প্রস্থ + অফসেটগুলিতে অন্তর্ভুক্ত।
ওটিওএইচ, গ্লিবিসি মেম্পপি দৈর্ঘ্যের উপর নির্ভর করে একটি ওভারল্যাপ সহ দুটি 4-বাইট লোড / স্টোর করবে so সুতরাং এটি সত্যিই পুরো জিনিসটি বুলিয়ানের শর্তাধীন শাখাগুলি মুক্ত করে। গ্লিবসি'র মেমকি / মেমোমোভের L(between_4_7):
ব্লকটি দেখুন । বা কমপক্ষে, মেমকপির ব্রাঞ্চিংয়ে বুলিয়ান উভয়ের জন্য একই আকারে একটি খণ্ড আকার নির্বাচন করুন।
যদি mov
ইনলাইন করা থাকে তবে আপনি 2x -সিমিয়েড + cmov
এবং শর্তসাপেক্ষ অফসেট ব্যবহার করতে পারেন বা স্ট্রিং ডেটা মেমরিতে রেখে দিতে পারেন।
অথবা যদি ইন্টেল আইস লেকের জন্য টিউন করা হয় ( ফাস্ট শর্ট আরইপি এমওভি বৈশিষ্ট্য সহ ), প্রকৃত পক্ষে সর্বোত্তম rep movsb
হতে পারে। glibc সেই বৈশিষ্ট্য সহ CPU- তে ছোট আকারের জন্য memcpy
ব্যবহার শুরু করতে পারে rep movsb
, যা অনেকগুলি ব্রাঞ্চিংয়ের সঞ্চয় করে।
ইউবি সনাক্তকরণ এবং অনিবার্য মানগুলির ব্যবহারের সরঞ্জাম
জিসিসি এবং ক্ল্যাং-এ আপনি -fsanitize=undefined
রান-টাইম উপকরণ যুক্ত করতে সংকলন করতে পারেন যা রানটাইম সময়ে ঘটে যাওয়া ইউবিতে সতর্কতা বা ত্রুটি ঘটবে। যদিও এটি এককীকরণযুক্ত ভেরিয়েবলগুলি ধরবে না। (কারণ এটি "অবিচ্ছিন্ন" বিটের জন্য জায়গা তৈরি করতে ধরণের আকারকে বাড়ায় না))
Https://developers.redhat.com/blog/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/ দেখুন
অবিচ্ছিন্ন তথ্য ব্যবহারের জন্য, ঝড় / এলএলভিএম-এ অ্যাড্রেস স্যানিটাইজার এবং মেমরি স্যানিটাইজার রয়েছে। https://github.com / clang -fsanitize=memory -fPIE -pie
গুগল / স্যানিটাইজারস / উইকি / মেমরিস্যানিটাইজার অবিরাম মেমরি পড়ার সনাক্তকরণের উদাহরণগুলি দেখায় । আপনি অপ্টিমাইজেশন ছাড়াই সংকলন করতে পারলে এটি সর্বোত্তমভাবে কাজ করতে পারে , সুতরাং ভেরিয়েবলগুলির সমস্ত পাঠ শেষ পর্যন্ত এসেমের মেমরি থেকে লোড হয়। তারা দেখায় যে এটি এমন -O2
কোনও ক্ষেত্রে ব্যবহৃত হচ্ছে যেখানে লোডটি অপ্টিমাইজ হবে না। আমি নিজে চেষ্টা করে দেখিনি। (কিছু ক্ষেত্রে, উদাহরণস্বরূপ কোনও অ্যারে যোগ করার আগে কোনও সংযোজককে সূচনা না করা, ঝনঝন -O3 এমন কোনও ভেক্টর রেজিস্টারে যে কোডটি আরম্ভ হয় নি তার প্রেরণ করবে So সুতরাং অপ্টিমাইজেশনের মাধ্যমে, আপনার ক্ষেত্রে এমন একটি ঘটনা ঘটতে পারে যেখানে ইউবির সাথে কোনও স্মৃতি পড়েনি memory .কিন্তু-fsanitize=memory
উত্পাদিত asm পরিবর্তন করে এবং এর জন্য একটি চেকের ফলাফল হতে পারে))
এটি অস্বীকারহীন মেমরির অনুলিপি সহ, এবং এটির সাথে সাধারণ যুক্তি এবং গাণিতিক ক্রিয়াকলাপ সহ্য করবে। সাধারণভাবে, মেমরিস্যানিটাইজার নিঃশব্দে স্মৃতিতে অবিচ্ছিন্ন ডেটা ছড়িয়ে দেওয়ার বিষয়টি সনাক্ত করে এবং একটি অবিশ্বাস্য মানের উপর নির্ভর করে কোনও কোড শাখা নেওয়া (বা নেওয়া হয় না) তা সতর্কতার প্রতিবেদন করে।
মেমরিস্যানিটাইজার ভালগ্রিড (মেমচেক সরঞ্জাম) এ পাওয়া কার্যকারিতার একটি উপসেট প্রয়োগ করে।
কারণ কল glibc করতে এই ক্ষেত্রে জন্য কাজ করা উচিত memcpy
সঙ্গে একটি length
গণনা uninitialized মেমরি থেকে উপর ভিত্তি করে (গ্রন্থাগার অভ্যন্তরীণ) একটি শাখা পরিণাম ডেকে আনবে length
। যদি এটি একটি সম্পূর্ণ শাখাবিহীন সংস্করণ সন্ধান করে যা সবেমাত্র ব্যবহৃত cmov
, সূচক এবং দুটি স্টোর ব্যবহার করেছে তবে এটি কাজ নাও করতে পারে।
ভালগ্রাইন্ডরাওmemcheck
এই ধরণের সমস্যাটি সন্ধান করবে, আবার প্রোগ্রামটি অননুমোদিতকরণের ডেটাগুলি অনুলিপি করে যদি অভিযোগ করে না। তবে এটি বলে যে এটি শনাক্তকরণের উপাত্তের উপর নির্ভর করে যে কোনও বাহ্যিক-দৃশ্যমান আচরণকে ধরার চেষ্টা করার জন্য "শর্তাধীন জাম্প বা চলাচল অবিঘ্নিত মান (গুলি) এর উপর নির্ভর করে" তা সনাক্ত করবে।
সম্ভবত কেবল একটি লোডকে পতাকাঙ্কিত না করার পিছনে ধারণাটি হ'ল স্ট্রাক্টগুলিতে প্যাডিং থাকতে পারে এবং পৃথক সদস্যরা কেবল একবারে একটি করে লেখা থাকলেও পুরো স্ট্রাক্টকে (প্যাডিং সহ) প্রশস্ত ভেক্টর লোড / স্টোর দিয়ে অনুলিপি করা কোনও ত্রুটি নয়। এএসএম স্তরে, কী প্যাডিং ছিল এবং আসলে মূল্যের একটি অংশ কী ছিল তার তথ্য হারিয়ে গেছে।