সি ++ প্রোগ্রামার সম্পর্কে জানা থাকা সমস্ত সাধারণ অপরিবর্তিত আচরণগুলি কী কী?
বলুন, যেমন:
a[i] = i++;
সি ++ প্রোগ্রামার সম্পর্কে জানা থাকা সমস্ত সাধারণ অপরিবর্তিত আচরণগুলি কী কী?
বলুন, যেমন:
a[i] = i++;
উত্তর:
NULL
পয়েন্টারmemcpy
ওভারল্যাপিং বাফারগুলি অনুলিপি করতে ব্যবহার করা ।int64_t i = 1; i <<= 72
অপরিজ্ঞাত)int i; i++; cout << i;
)volatile
বা অন্য কোনও ধরণের অবজেক্টের মান ব্যবহার করাsig_atomic_t
long int
#if
অভিব্যক্তিতে সংজ্ঞায়িত টোকেন তৈরি করাক্রমের প্যারামিটারগুলি যে ক্রমের মূল্যায়ন করা হয় তা অনির্দিষ্ট আচরণ । (এই আপনার প্রোগ্রাম ক্র্যাশ অর্ডার পিজা করতে হবে না, বিস্ফোরিত করা, অথবা ... অসদৃশ অনির্ধারিত আচরণ ।)
একমাত্র প্রয়োজন হ'ল ফাংশনটি বলার আগে সমস্ত পরামিতিগুলি সম্পূর্ণরূপে মূল্যায়ন করা উচিত।
এই:
// The simple obvious one.
callFunc(getA(),getB());
এর সমতুল্য হতে পারে:
int a = getA();
int b = getB();
callFunc(a,b);
অথবা এটা:
int b = getB();
int a = getA();
callFunc(a,b);
এটি হয়ও হতে পারে; এটি সংকলক পর্যন্ত। পার্শ্ব প্রতিক্রিয়াগুলির উপর নির্ভর করে ফলাফলটি গুরুত্বপূর্ণ হতে পারে।
সংকলকটি একটি অভিব্যক্তির মূল্যায়ন অংশগুলিকে পুনরায় অর্ডার করতে মুক্ত (অর্থটি অপরিবর্তিত রয়েছে বলে ধরে নেওয়া)।
মূল প্রশ্ন থেকে:
a[i] = i++;
// This expression has three parts:
(a) a[i]
(b) i++
(c) Assign (b) to (a)
// (c) is guaranteed to happen after (a) and (b)
// But (a) and (b) can be done in either order.
// See n2521 Section 5.17
// (b) increments i but returns the original value.
// See n2521 Section 5.2.6
// Thus this expression can be written as:
int rhs = i++;
int lhs& = a[i];
lhs = rhs;
// or
int lhs& = a[i];
int rhs = i++;
lhs = rhs;
ডাবল চেকড লকিং এবং একটি সহজ ভুল করা।
A* a = new A("plop");
// Looks simple enough.
// But this can be split into three parts.
(a) allocate Memory
(b) Call constructor
(c) Assign value to 'a'
// No problem here:
// The compiler is allowed to do this:
(a) allocate Memory
(c) Assign value to 'a'
(b) Call constructor.
// This is because the whole thing is between two sequence points.
// So what is the big deal.
// Simple Double checked lock. (I know there are many other problems with this).
if (a == null) // (Point B)
{
Lock lock(mutex);
if (a == null)
{
a = new A("Plop"); // (Point A).
}
}
a->doStuff();
// Think of this situation.
// Thread 1: Reaches point A. Executes (a)(c)
// Thread 1: Is about to do (b) and gets unscheduled.
// Thread 2: Reaches point B. It can now skip the if block
// Remember (c) has been done thus 'a' is not NULL.
// But the memory has not been initialized.
// Thread 2 now executes doStuff() on an uninitialized variable.
// The solution to this problem is to move the assignment of 'a'
// To the other side of the sequence point.
if (a == null) // (Point B)
{
Lock lock(mutex);
if (a == null)
{
A* tmp = new A("Plop"); // (Point A).
a = tmp;
}
}
a->doStuff();
// Of course there are still other problems because of C++ support for
// threads. But hopefully these are addresses in the next standard.
আমার প্রিয় "টেমপ্লেটগুলির তাত্ক্ষণীতে অসীম পুনরাবৃত্তি" কারণ আমি বিশ্বাস করি এটি সঙ্কলনের সময় একমাত্র অপরিবর্তিত আচরণ ঘটে occurs
অপরিজ্ঞাত আচরণের পাশাপাশি , সমানভাবে বাজে বাস্তবায়ন-সংজ্ঞায়িত আচরণও রয়েছে ।
অপরিজ্ঞাত আচরণটি ঘটে যখন কোনও প্রোগ্রাম কিছু করে যার ফলাফলটি মান দ্বারা নির্দিষ্ট করা হয় না।
বাস্তবায়ন-সংজ্ঞায়িত আচরণ একটি প্রোগ্রামের দ্বারা করা একটি ক্রিয়া যার ফলাফলটি মান দ্বারা সংজ্ঞায়িত হয় না, তবে যা বাস্তবায়নের জন্য ডকুমেন্টের প্রয়োজন হয়। স্ট্যাক ওভারফ্লো প্রশ্ন থেকে একটি উদাহরণ "মাল্টবাইট চরিত্রের অক্ষর", এটির কোনও সংকলন করতে ব্যর্থ এমন কোনও সি সংকলক আছে কি?।
বাস্তবায়ন-সংজ্ঞায়িত আচরণ কেবল তখনই আপনাকে কামড়ায় যখন আপনি পোর্টিং শুরু করেন (তবে সংকলকের নতুন সংস্করণে আপগ্রেড করাও পোর্টিং হয়!)
ভেরিয়েবলগুলি কেবলমাত্র একটি এক্সপ্রেশনে আপডেট করা যেতে পারে (প্রযুক্তিগতভাবে একবার সিকোয়েন্স পয়েন্টের মধ্যে)।
int i =1;
i = ++i;
// Undefined. Assignment to 'i' twice in the same expression.
বিভিন্ন পরিবেশের সীমাবদ্ধতার একটি প্রাথমিক বোঝাপড়া। পুরো তালিকাটি সি স্পেসিফিকেশনের 5.2.4.1 বিভাগে রয়েছে। এখানে কয়েকটি দেওয়া হয়েছে;
আমি স্যুইচ স্টেটমেন্টের জন্য 1023 কেস লেবেলের সীমাটি দেখে কিছুটা অবাক হয়েছিলাম, আমি জোর করে বলতে পারি যে উত্পন্ন কোড / লেক্স / পার্সারগুলির পক্ষে মোটামুটি সহজভাবে ছাড়িয়ে গিয়েছি।
যদি এই সীমাগুলি অতিক্রম করা হয়, তবে আপনার আচরণের সংজ্ঞা (ক্র্যাশ, সুরক্ষা ত্রুটি, ইত্যাদি ...) রয়েছে।
ঠিক আছে, আমি জানি এটি সি স্পেসিফিকেশন থেকে এসেছে তবে সি ++ এই মূল সমর্থনগুলি ভাগ করে shares
memcpy
ওভারল্যাপিং মেমরি অঞ্চলগুলির মধ্যে অনুলিপি করতে ব্যবহার করা। উদাহরণ স্বরূপ:
char a[256] = {};
memcpy(a, a, sizeof(a));
আচরণটি সি স্ট্যান্ডার্ড অনুসারে সংজ্ঞায়িত, যা সি ++ 03 স্ট্যান্ডার্ড দ্বারা গ্রহণ করা হয়।
সংক্ষিপ্তসার
1 / # অন্তর্ভুক্ত শূন্য * মেমকি (শূন্য * সীমাবদ্ধ এস 1, কনস্টুট শূন্য * সীমাবদ্ধ এস 2, আকার_t এন);
বিবরণ
2 / মেমকি ফাংশনটি এস 2 দ্বারা নির্দেশিত বস্তুর মধ্যে এস 1 দ্বারা নির্দেশিত বস্তু থেকে n অক্ষর অনুলিপি করে। যদি অনুলিপি করা বস্তুগুলির মধ্যে অনুলিপি হয় তবে আচরণটি সংজ্ঞায়িত। রিটার্ন 3 মেমকি ফাংশন এস 1 এর মান প্রদান করে।
সংক্ষিপ্তসার
1 # শূন্য * মেমোমোভ অন্তর্ভুক্ত করুন (শূন্য * এস 1, কনস্টেট শূন্য * এস 2, আকার_t এন);
বিবরণ
2 মেমমোভ ফাংশন এস 2 দ্বারা নির্দেশিত বস্তুর মধ্যে এস 1 দ্বারা নির্দেশিত বস্তু থেকে n অক্ষর অনুলিপি করে। অনুলিপিটি সংঘটিত হয় যেমন s2 দ্বারা নির্দেশিত বস্তু থেকে এন অক্ষরগুলি প্রথমে এন অক্ষরের অস্থায়ী অ্যারেতে অনুলিপি করা হয় যা s1 এবং s2 দ্বারা নির্দেশিত বস্তুগুলিকে ওভারল্যাপ করে না এবং তারপরে অস্থায়ী অ্যারে থেকে এন অক্ষরগুলি অনুলিপি করা হয় s1 দ্বারা নির্দেশিত বস্তু। রিটার্নস
3 মেমমোভ ফাংশন এস 1 এর মান প্রদান করে।
একমাত্র প্রকার যার জন্য সি ++ একটি আকারের গ্যারান্টি দেয় char
। এবং আকারটি হল 1. অন্যান্য সমস্ত ধরণের আকার প্ল্যাটফর্ম নির্ভর।