compiler - c++ tutorial pdf




অনির্ধারিত আচরণ এবং ক্রম পয়েন্ট (4)

"ক্রম পয়েন্ট" কি কি?

অনির্দিষ্ট আচরণ এবং ক্রম পয়েন্ট মধ্যে সম্পর্ক কি?

আমি প্রায়ই a[++i] = i; মত মজার এবং ধাঁধা অভিব্যক্তি ব্যবহার করুন a[++i] = i; , নিজেকে ভাল বোধ করতে। কেন আমি তাদের ব্যবহার বন্ধ করা উচিত?

যদি আপনি এটি পড়েন তবে অনুসরণের প্রশ্নটি দেখার জন্য নিশ্চিত হন অনির্ধারিত আচরণ এবং ক্রম পয়েন্ট পুনরায় লোড করা

(দ্রষ্টব্য: এটি স্ট্যাক ওভারফ্লো এর C ++ FAQ- এ প্রবেশ করার অর্থ। যদি আপনি এই ফর্মটিতে একটি FAQ প্রদানের ধারণাটি সমালোচনা করতে চান তবে মেটাতে যে পোস্টটি শুরু হয়েছে তা পোস্ট করার জায়গা হবে। সেই প্রশ্নটি সি ++ চ্যাটরুমে নজরদারি করা হয়, যেখানে প্রথমবারের মত প্রায়শই জিজ্ঞাসিত প্রশ্নটি শুরু হয়েছিল, তাই আপনার উত্তরটি যারা ধারণা নিয়ে এসেছে তাদের দ্বারা পড়ার সম্ভাবনা খুব বেশি।)


সি ++ 98 এবং সি ++ 03

এই উত্তরটি C ++ স্ট্যান্ডার্ডের পুরানো সংস্করণের জন্য। সি ++ 11 এবং সি ++ স্ট্যান্ডার্ডগুলির 14 সংস্করণ আনুষ্ঠানিকভাবে 'ক্রম পয়েন্ট' ধারণ করে না; অপারেশনগুলি 'আগে সিকোয়েন্সেড' বা 'অননুমোদিত' বা 'indeterminately sequenced' পরিবর্তে হয়। নেট প্রভাব অপরিহার্য একই, কিন্তু পরিভাষা ভিন্ন।

অস্বীকৃতি : ঠিক আছে। এই উত্তর একটি বিট দীর্ঘ। তাই এটা পড়ার সময় ধৈর্য আছে। যদি আপনি ইতিমধ্যে এই জিনিস জানেন, আবার তাদের পড়া আপনাকে পাগল করা হবে না।

প্রাক প্রয়োজনীয়তা : সি ++ স্ট্যান্ডার্ড একটি প্রাথমিক জ্ঞান

ক্রম পয়েন্ট কি কি?

স্ট্যান্ডার্ড বলছে

নির্দিষ্ট নির্দিষ্ট বিন্দুতে ক্রমিক পয়েন্ট নামক এক্সিকিউশন ক্রম এ, পূর্ববর্তী মূল্যায়নগুলির সমস্ত পার্শ্ব প্রতিক্রিয়া সম্পূর্ণ হবে এবং পরবর্তী মূল্যায়নগুলির কোনও পার্শ্ব প্রতিক্রিয়া সংঘটিত হবে না। (§1.9 / 7)

ক্ষতিকর দিক? পার্শ্ব প্রতিক্রিয়া কি কি?

একটি অভিব্যক্তি মূল্যায়ন কিছু উৎপন্ন করে এবং যদি এর সাথে মৃত্যুদন্ড পরিবেশের অবস্থার পরিবর্তন ঘটে তবে বলা হয় যে অভিব্যক্তিটির (তার মূল্যায়ন) কিছু পার্শ্ব প্রতিক্রিয়া আছে।

উদাহরণ স্বরূপ:

int x = y++; //where y is also an int

শুরু করার অপারেশন ছাড়াও ++ অপারেটরের পার্শ্ব প্রতিক্রিয়াটির কারণে y এর মান পরিবর্তিত হয়।

এ পর্যন্ত সব ঠিকই. ক্রম পয়েন্ট চলন্ত। Comp.lang.c লেখক Steve Summit দ্বারা প্রদত্ত seq-points এর একটি বিকল্প সংজ্ঞা:

ধারাবাহিক বিন্দুটি এমন একটি বিন্দু যা ধুলো স্থির হয়ে গেছে এবং এ পর্যন্ত যে সমস্ত পার্শ্ব প্রতিক্রিয়া দেখা গেছে তা সম্পূর্ণ হওয়া নিশ্চিত।

সি ++ স্ট্যান্ডার্ড তালিকাভুক্ত সাধারণ ক্রম পয়েন্ট কি কি?

ঐগুলি:

  • পূর্ণ অভিব্যক্তিটির মূল্যায়ন শেষে ( §1.9/16 ) (একটি সম্পূর্ণ অভিব্যক্তি এমন একটি অভিব্যক্তি যা অন্য অভিব্যক্তিটির উপসর্গ নয়।) 1

উদাহরণ:

int a = 5; // ; is a sequence point here
  • প্রথম অভিব্যক্তি ( §1.9/18 ) 2 এর মূল্যায়ন করার পরে নিচের প্রতিটি এক্সপ্রেশনগুলির মূল্যায়নে 2

    • a && b (§5.14)
    • a || b (§5.15)
    • a ? b : c (§5.16)
    • a , b (§5.18) (এখানে একটি, b একটি কমা অপারেটর; func(a,a++) , কমা অপারেটর নয়, এটি শুধুমাত্র a এবং a++ আর্গুমেন্টগুলির মধ্যে বিভাজক। সুতরাং আচরণটি সেই ক্ষেত্রে অনির্দিষ্ট (যদি a আদিম টাইপ বলে মনে করা হয়))
  • ফাংশন কলের ( §1.9/17 ) কোনও এক্সপ্রেশন বা বিবৃতি কার্যকর করার আগে সঞ্চালিত সমস্ত ফাংশন আর্গুমেন্ট (যদি থাকে) এর মূল্যায়ন করার পরে কোনও ফাংশন কলটিতে (ফাংশনটি ইনলাইন হয় কিনা)।

1: দ্রষ্টব্য: পূর্ণ-অভিব্যক্তিটির মূল্যায়নে উপ-এক্সপ্রেশনগুলির মূল্যায়ন অন্তর্ভুক্ত থাকতে পারে যা পূর্ণ-অভিব্যক্তিটির মূল অংশ নয়। উদাহরণস্বরূপ, ডিফল্ট আর্গুমেন্ট এক্সপ্রেশন (8.3.6) মূল্যায়ন করতে জড়িত সাব এক্সপ্রেশনগুলি ফাংশনকে কল করে এমন অভিব্যক্তিতে তৈরি করা হয়, ডিফল্ট যুক্তি নির্ধারণ করে এমন অভিব্যক্তি নয়

2: নির্দেশিত অপারেটরগুলি হল বিল্ট-ইন অপারেটরস, যেমনটি 5 অনুচ্ছেদে বর্ণিত হয়েছে। যখন এই অপারেটরগুলির মধ্যে একটি কার্যকর প্রেক্ষাপটে ওভারলোড করা হয় (ধারা 13), এইভাবে ব্যবহারকারী-সংজ্ঞায়িত অপারেটর ফাংশন নির্ধারণ করা হয়, তখন অভিব্যক্তিটি একটি ফাংশন আহ্বান নির্ধারণ করে এবং operands তাদের মধ্যে একটি implied ক্রম বিন্দু ছাড়া, একটি যুক্তি তালিকা গঠন।

অনির্ধারিত আচরণ কি?

মান বিভাগ §1.3.12 হিসাবে অনির্ধারিত আচরণ সংজ্ঞায়িত

আচরণ, যেমন একটি ভুল প্রোগ্রাম নির্মাণ বা ভুল তথ্য ব্যবহারের উপর উদ্ভূত হতে পারে, যার জন্য এই আন্তর্জাতিক স্ট্যান্ডার্ড কোন প্রয়োজনীয়তা প্রযোজ্য 3

এই ইন্টারন্যাশনাল স্ট্যান্ডার্ডটি আচরণের কোন সুস্পষ্ট সংজ্ঞাটির বিবরণকে বাদ দিয়ে অনির্ধারিত আচরণও প্রত্যাশিত হতে পারে।

3: অনুমতিহীন অনির্ধারিত আচরণটি অনুপস্থিত ফলাফলগুলির সাথে সম্পূর্ণভাবে উপেক্ষা করা, অনুবাদ বা প্রোগ্রাম কার্যকরকরণের সময় পরিবেশগতভাবে (কোনও ডায়গনিস্টিক মেসেজ প্রদানের সাথে বা বাইরে-বের করে), একটি অনুবাদ বা মৃত্যুদণ্ড কার্যকর করার জন্য প্রোগ্রামের প্রয়োগের সময় আচরণ করা। (একটি ডায়গনিস্টিক বার্তা প্রদান সঙ্গে)।

সংক্ষেপে, অনির্ধারিত আচরণ মানে আপনার নাক থেকে উড়ন্ত ডিমনগুলি গর্ভবতী হওয়া আপনার বান্ধবীকে যেকোনো কিছু হতে পারে।

অনির্ধারিত আচরণ এবং ক্রম পয়েন্ট মধ্যে সম্পর্ক কি?

আমি এটি পেতে আগে আপনি অনির্দিষ্ট আচরণ, অনির্দিষ্ট আচরণ এবং বাস্তবায়ন নির্ধারিত আচরণ মধ্যে পার্থক্য (গুলি) জানা আবশ্যক।

আপনাকে অবশ্যই জানাতে হবে যে the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified

উদাহরণ স্বরূপ:

int x = 5, y = 6;

int z = x++ + y++; //it is unspecified whether x++ or y++ will be evaluated first.

here আরেকটি উদাহরণ।

এখন স্ট্যান্ডার্ড §5/4 বলছেন

  • 1) পূর্ববর্তী এবং পরবর্তী ক্রম বিন্দুতে একটি স্কেল বস্তুটি একটি অভিব্যক্তির মূল্যায়ন দ্বারা সর্বাধিক একবার তার সংরক্ষিত মানটি সংশোধন করবে।

এর মানে কী?

আনুষ্ঠানিকভাবে এটি দুটি ক্রম পয়েন্টের মধ্যে একটি পরিবর্তনশীল অবশ্যই একাধিকবার সংশোধন করা উচিত নয়। একটি এক্সপ্রেশন বিবৃতিতে, next sequence point সাধারণত সমাপ্তির সেমিকোলন হয়, এবং previous sequence point আগের বিবৃতির শেষে হয়। একটি অভিব্যক্তি মধ্যবর্তী sequence points থাকতে পারে।

উপরের বাক্য থেকে নিম্নলিখিত অভিব্যক্তি অনির্ধারিত আচরণ আহ্বান করে:

i++ * ++i;   // UB, i is modified more than once btw two SPs
i = ++i;     // UB, same as above
++i = 2;     // UB, same as above
i = ++i + 1; // UB, same as above
++++++i;     // UB, parsed as (++(++(++i)))

i = (i, ++i, ++i); // UB, there's no SP between `++i` (right most) and assignment to `i` (`i` is modified more than once btw two SPs)

কিন্তু নিম্নলিখিত এক্সপ্রেশন জরিমানা:

i = (i, ++i, 1) + 1; // well defined (AFAIK)
i = (++i, i++, i);   // well defined 
int j = i;
j = (++i, i++, j*i); // well defined
  • 2) উপরন্তু, পূর্বে মূল্য সংরক্ষণ করা হবে মান নির্ধারণ শুধুমাত্র অ্যাক্সেস করা হবে।

এর মানে কী? এর অর্থ যদি কোনও বস্তুর পূর্ণ অভিব্যক্তিতে লিখিত হয় তবে একই অভিব্যক্তিটির মধ্যে যেকোনও এবং তার সমস্ত অ্যাক্সেস সরাসরি লিখিত মূল্যের গণনাটিতে জড়িত হওয়া আবশ্যক

উদাহরণস্বরূপ i = i + 1 সমস্ত অ্যাক্সেস (LHS এবং RHS তে) সরাসরি লিখিত মূল্যের গণনার সাথে জড়িত । সুতরাং এটা জরিমানা।

এই নিয়মটি কার্যকরভাবে আইনী অভিব্যক্তিগুলিকে বিধিনিষেধযুক্ত করে, যা বিক্ষোভের পূর্বে বিক্ষোভকে অ্যাক্সেস করে।

উদাহরণ 1:

std::printf("%d %d", i,++i); // invokes Undefined Behaviour because of Rule no 2

উদাহরণ 2:

a[i] = i++ // or a[++i] = i or a[i++] = ++i etc

অনুমোদিত নয় কারণ i ( a[i] অ্যাক্সেসের মধ্যে একটিতে এমন মানটির সাথে কিছু করার নেই যা আমার মধ্যে সংরক্ষণ করা শেষ হয় (যা i++ মধ্যে ঘটতে), এবং তাই সংজ্ঞায়িত করার কোনও ভাল উপায় নেই - হয় আমাদের বোঝার জন্য বা কম্পাইলারের জন্য - কিনা অ্যাক্সেসেড মান আগে বা পরে অ্যাক্সেস করা উচিত। তাই আচরণ অনির্দিষ্ট হয়।

উদাহরণ 3:

int x = i + i++ ;// Similar to above

here C ++ 11 এর জন্য উত্তর অনুসরণ here


পরিবর্তনের জন্য একটি মৌলিক কারণ আমি অনুমান করছি, পুরানো ব্যাখ্যাটি পরিষ্কার করার জন্য এটি শুধুমাত্র অঙ্গরাগ নয়: কারণটি সমান্তরাল। বর্ধিতকরণের অনির্দিষ্ট আদেশটি কেবল সম্ভাব্য কয়েকটি সিরিয়াল ক্রমগুলির মধ্যে একটি নির্বাচন মাত্র, এটি অর্ডারের আগে এবং পরে পুরোপুরি ভিন্ন, কারণ যদি কোন নির্দিষ্ট আদেশ না থাকে তবে সমান্তরাল মূল্যায়ন সম্ভব: পুরানো বিধিগুলির সাথে নয়। উদাহরণস্বরূপ:

f (a,b)

পূর্বে হয় তারপর একটি তারপর বি, বা, তারপর বি। এখন, একটি এবং বি interleaved নির্দেশাবলী বা এমনকি বিভিন্ন কোর উপর মূল্যায়ন করা যাবে।


এটি আমার আগের উত্তরটির একটি ফলো আপ এবং C ++ 11 সম্পর্কিত উপাদান রয়েছে।

পূর্বের প্রয়োজনীয়তা : সম্পর্কের প্রাথমিক জ্ঞান (গণিত)।

এটা কি সি ++ 11 এ কোন ক্রমিক পয়েন্ট নেই?

হ্যাঁ! এই খুব সত্য।

সিঙ্কেন্স পয়েন্টগুলি সি ++ 11 এর আগে এবং ক্রমানুযায়ী (এবং প্রত্যাশিত এবং সংজ্ঞায়িতভাবে ক্রমানুসারে ) relations সাথে ক্রম অনুসারে প্রতিস্থাপিত হয়েছে।

ঠিক কি এই 'আগে sequenced' জিনিস?

আগে নির্ধারিত (§1.9 / 13) একটি সম্পর্ক যা:

একটি একক thread দ্বারা মৃত্যুদন্ড কার্যকর এবং একটি কঠোর আংশিক আদেশ induces মধ্যে 1

আনুষ্ঠানিকভাবে এর মানে হল যে কোনও দুটি মূল্যায়ন দেওয়া হয়েছে (নিচে দেখুন) A এবং B , যদি A B আগে অনুক্রমিত হয়, তবে এটিকে কার্যকর করা B এর কার্যকর হওয়ার পূর্বে । যদি A এবং B আগে অনুক্রমিত না হয় A আগে অনুক্রমিত না হয় তবে A এবং B অকার্যকর হয় 2

মূল্যায়ন A এবং B অনিশ্চিতভাবে অনুক্রমিত হয় যখন A বা B আগে অনুক্রমিত হয় A আগে অনুক্রমিত হয় তবে এটি অনির্দিষ্ট যা 3

[নোট]
1: একটি কঠোর আংশিক ক্রম হচ্ছে একটি সেট P উপর একটি বাইনারি সম্পর্ক "<" যা Asymmetric , এবং Transitive , অর্থাত্, P , এ, এবং c উভয়ের জন্য, আমাদের কাছে আছে:
........ (ঝ)। যদি একটি <বি তারপর ¬ (বি <একটি) ( asymmetry );
........ (২)। যদি <b এবং b <c তারপর একটি <c ( transitivity )।
2: অপ্রাপ্তবয়স্ক মূল্যায়নের নির্বাহ ওভারল্যাপ করতে পারেন।
3: Indeterminately অনুক্রমিক মূল্যায়ন overlap করতে পারে না, কিন্তু হয় প্রথম নির্বাহ করা যেতে পারে।

সি ++ 11 প্রসঙ্গে 'মূল্যায়ন' শব্দটির অর্থ কী?

সি ++ 11 এ, সাধারণভাবে একটি অভিব্যক্তি (বা একটি উপ-অভিব্যক্তি) মূল্যায়ন অন্তর্ভুক্ত রয়েছে:

  • মান কম্পিউটেশনস ( গ্লাভ্যু মূল্যায়নের জন্য একটি বস্তুর পরিচয় নির্ধারণ এবং পূর্ববর্তী মূল্যবোধের জন্য একটি বস্তুর পূর্বে নির্ধারিত মান আনয়ন সহ ) এবং

  • পার্শ্ব প্রতিক্রিয়া দীক্ষা।

এখন (§1.9 / 14) বলেছেন:

প্রতিটি মান গণনা এবং পূর্ণ-অভিব্যক্তিটির সাথে যুক্ত পার্শ্ব প্রতিক্রিয়া মূল্যায়ন করার জন্য পরবর্তী পূর্ণ-অভিব্যক্তিটির সাথে যুক্ত প্রতিটি মান গণনা এবং পার্শ্ব প্রতিক্রিয়ার আগে অনুক্রমিত হয়।

  • তুচ্ছ উদাহরণ:

    int x; x = 10; ++x;

    মান গণনা এবং ++x সাথে যুক্ত পার্শ্ব প্রতিক্রিয়া মান গণনা এবং x = 10; এর পার্শ্ব প্রতিক্রিয়া পরে অনুক্রমিত হয় x = 10;

সুতরাং অনির্ধারিত আচরণ এবং উপরে উল্লিখিত জিনিসগুলির মধ্যে কিছু সম্পর্ক থাকতে হবে, তাই না?

হ্যাঁ! ঠিক।

ইন (§1.9 / 15) এটি উল্লেখ করা হয়েছে যে

যেখানে উল্লেখ করা হয়েছে, পৃথক অপারেটরদের অপারেটিং এবং পৃথক এক্সপ্রেশনগুলির সাব এক্সপ্রেসেশনগুলির মূল্যায়ন অপ্রকাশিত 4

উদাহরণ স্বরূপ :

int main()
{
     int num = 19 ;
     num = (num << 3) + (num >> 3);
} 
  1. অপারেটরের মূল্যায়ন অপারেটর একে অপরের আপেক্ষিক অপ্রাপ্তবয়স্ক।
  2. << এবং >> অপারেটরদের অপারেটিং মূল্যায়ন একে অপরকে অপ্রতিরোধ্য।

4: এমন একটি অভিব্যক্তি যা একটি প্রোগ্রাম কার্যকর করার সময় একবারের বেশি মূল্যায়ন করা হয়, তার উপসম্পাদনের অনুপযুক্ত এবং অনিশ্চিতভাবে অনুক্রমিক মূল্যায়নগুলি বিভিন্ন মূল্যায়নে ধারাবাহিকভাবে সঞ্চালিত হওয়ার প্রয়োজন হয় না।

(§1.9 / 15) অপারেটরের অপারেটিংগুলির মান কম্পিউটেশনগুলি অপারেটরের ফলাফলের মান গণনা করার আগে অনুক্রমিত হয়।

মানে x + y x এবং y এর মান গণনা মান (x + y) এর মান গণনা করার আগে অনুক্রমিত হয়।

অধিক গুরুত্বের সাথে

(§1.9 / 15) যদি স্কলার বস্তুর কোনও পার্শ্ব প্রতিক্রিয়া হয় অপ্রাপ্তবয়স্ক হয়

(একটি) একই scalar বস্তুর অন্য পার্শ্ব প্রতিক্রিয়া

অথবা

(খ) একই স্কেলার বস্তুর মান ব্যবহার করে একটি মান গণনা।

আচরণ অনির্দিষ্ট হয়

উদাহরণ:

int i = 5, v[10] = { };
void  f(int,  int);
  1. i = i++ * ++i; // Undefined Behaviour
  2. i = ++i + i++; // Undefined Behaviour
  3. i = ++i + ++i; // Undefined Behaviour
  4. i = v[i++]; // Undefined Behaviour
  5. i = v[++i]: // Well-defined Behavior
  6. i = i++ + 1; // Undefined Behaviour
  7. i = ++i + 1; // Well-defined Behaviour
  8. ++++i; // Well-defined Behaviour
  9. f(i = -1, i = -1); // Undefined Behaviour (see below)

কোনও ফাংশন কল করার সময় (ফাংশনটি ইনলাইন হয় কিনা বা না), প্রতিটি মূল্য গণনা এবং কোনও আর্গুমেন্ট অভিব্যক্তি সহ পার্শ্ব প্রতিক্রিয়া বা বলা ফাংশন নির্ধারণকারী পোস্টফিক্স অভিব্যক্তি সহ, শরীরের প্রতিটি অভিব্যক্তি বা বিবৃতি কার্যকর করার আগে অনুক্রমিত হয় ফাংশন বলা। [ দ্রষ্টব্য: বিভিন্ন যুক্তি এক্সপ্রেশনগুলির সাথে যুক্ত মান গণনা এবং পার্শ্ব প্রতিক্রিয়া অপ্রত্যক্ষ । - শেষ নোট ]

এক্সপ্রেশন (5) , (7) এবং (8) অনির্দিষ্ট আচরণ আহ্বান করবেন না। আরো বিস্তারিত ব্যাখ্যা জন্য নিম্নলিখিত উত্তর পরীক্ষা করে দেখুন।

চূড়ান্ত নোট :

আপনি পোস্টে কোন ত্রুটি খুঁজে পেতে হলে একটি মন্তব্য করুন। পাওয়ার-ব্যবহারকারীরা (rep> 20000 সহ) টাইপস এবং অন্যান্য ভুল সংশোধন করার জন্য পোস্টটি সম্পাদনা করতে দ্বিধা করবেন না।


সি ++ 17 ( N4659 ) একটি প্রস্তাব অন্তর্ভুক্ত করেছে যা N4659 সি ++ এর জন্য N4659 এক্সপ্রেশন মূল্যায়ন আদেশ যা অভিব্যক্তি মূল্যায়নটির কঠোর N4659 সংজ্ঞায়িত করে।

বিশেষ করে, নিম্নলিখিত বাক্য যোগ করা হয়েছে:

8.18 নিয়োগ এবং যৌগিক নিয়োগ অপারেটর :
....

সব ক্ষেত্রে, অ্যাসাইনমেন্টটি ডান এবং বাম অপারেডগুলির মান গণনা এবং অ্যাসাইনমেন্ট অভিব্যক্তিটির মান গণনা করার পরে অনুক্রমিত হয়। ডান অপারেড বাম অপারেড আগে ক্রম।

এটি পূর্বনির্ধারিত পূর্বনির্ধারিত আচরণের বেশ কয়েকটি ক্ষেত্রে বৈধ, যার মধ্যে একটি প্রশ্ন রয়েছে:

a[++i] = i;

তবে বেশ কিছু অন্যান্য অনুরূপ ক্ষেত্রে এখনও অনির্দিষ্ট আচরণের দিকে পরিচালিত করে।

N4140 :

i = i++ + 1; // the behavior is undefined

কিন্তু N4659

i = i++ + 1; // the value of i is incremented
i = i++ + i; // the behavior is undefined

অবশ্যই, একটি সি ++ 17 সঙ্গতিপূর্ণ কম্পাইলার ব্যবহার করার অর্থ অপরিহার্যভাবে এইরকম এক্সপ্রেশন লিখতে শুরু করা উচিত নয়।







sequence-points