অনুশীলনে, কেন বিভিন্ন সংকলকগণ x x +++ + ++ i; এর বিভিন্ন মানের গণনা করবে ??


164

এই কোডটি বিবেচনা করুন:

int i = 1;
int x = ++i + ++i;

একটি সংকলক এই কোডটি সংকলন করে ধরেই নিতে পারে তার জন্য আমাদের কিছু অনুমান আছে।

  1. উভয়ই ++iফিরে আসে 2, যার ফলস্বরূপ x=4
  2. একটি ++iরিটার্ন দেয় 2এবং অন্যটি রিটার্ন দেয় 3যার ফলস্বরূপ x=5
  3. উভয়ই ++iফিরে আসে 3, যার ফলস্বরূপ x=6

আমার কাছে, দ্বিতীয়টি সম্ভবত খুব সম্ভবত বলে মনে হচ্ছে। দুটি ++অপারেটরের মধ্যে একটির সাথে মৃত্যুদন্ড কার্যকর করা হয় i = 1, iবর্ধিত হয় এবং ফলাফলটি 2ফিরে আসে। তারপরে দ্বিতীয় ++অপারেটরটি দিয়ে মৃত্যুদন্ড কার্যকর করা হয় i = 2, iবর্ধিত হয় এবং ফলাফলটি 3ফিরে আসে। তারপর 2এবং 3দিতে একসাথে যুক্ত করা হয় 5

যাইহোক, আমি ভিজ্যুয়াল স্টুডিওতে এই কোডটি চালিয়েছি, এবং ফলাফল ছিল 6। আমি সংকলকগুলি আরও ভাল করে বোঝার চেষ্টা করছি এবং আমি ভাবছি যে সম্ভবত কী ফলাফল হতে পারে 6। আমার একমাত্র অনুমান যে কোডটি কিছু "বিল্ট-ইন" সম্মতি দিয়ে কার্যকর করা যেতে পারে। ++অপারেটর দুটি ডাকা হয়েছিল, একে iঅপর ফিরে আসার পূর্বে প্রত্যেকটি বর্ধিত হয়েছিল, এবং তারপরে তারা দুজনেই ফিরে এসেছিল 3। এটি কল স্ট্যাক সম্পর্কে আমার বোঝার বিরোধিতা করবে এবং এগুলি ব্যাখ্যা করার প্রয়োজন হবে।

একটি C++সংকলক এমন কোন জিনিস (যুক্তিসঙ্গত) করতে পারে যা 4ফলাফল বা ফলাফলের দিকে নিয়ে যায় বা 6?

বিঃদ্রঃ

এই উদাহরণটি বার্জন স্ট্রস্ট্রপের প্রোগ্রামিংয়ে অপরিবর্তিত আচরণের উদাহরণ হিসাবে উপস্থিত হয়েছিল: সি ++ (সি ++ 14) ব্যবহার করে নীতি ও অনুশীলন।

দেখুন দারুচিনি এর মন্তব্য


4
সি স্পেসটি কেবল বাম দিকে, প্রাক / উত্তরোত্তর ক্রিয়াকলাপের তুলনায় = ডান দিকে অপারেশন বা মূল্যায়নের ক্রমটি কভার করে না।
ক্রিস্টোবল পলিক্রোনপোলিস

4
আপনি যদি স্ট্রস্ট্রস্ট্রপের কোনও বই থেকে উত্তরটি পেয়েছেন (উত্তরের একটিতে মন্তব্য হিসাবে উল্লেখ করা হয়েছে) উদাহরণটি পেয়ে থাকেন তবে আপনাকে প্রশ্নে প্রশংসা দেওয়ার পরামর্শ দিন।
ড্যানিয়েল আর কলিন্স

4
@ ফিলিপ্সি আপনার প্রস্তাবিত সদৃশ এই প্রশ্নের সদৃশ নয়। প্রশ্নগুলি আলাদা। আপনার প্রস্তাবিত সদৃশ জবাব এই প্রশ্নের উত্তর দেয় না। আপনার প্রস্তাবিত সদৃশ জবাব উত্তর এই প্রশ্নের গৃহীত (বা উচ্চ ভোট) উত্তর (গুলি) এর সদৃশ নয়। আমি বিশ্বাস করি আপনি আমার প্রশ্নটি ভুলভাবে পড়েছেন। আমি আপনাকে এটি পুনরায় পড়ার এবং ভোটটি বন্ধ করার জন্য পুনর্বিবেচনা করার পরামর্শ দিচ্ছি।
দারুচিনি

4
@ ফিলিপ্সি "উত্তরগুলি বলে যে একটি সংকলক কিছু করতে পারে ..." এটি আমার প্রশ্নের উত্তর দেয় না। "তারা দেখায় যে আপনি যদি নিজের প্রশ্নটি আলাদা বলে মনে করেন তবে এটি কেবলমাত্র তার একটি বৈচিত্র মাত্র" কী? "যদিও আপনি আপনার সি ++ এর সংস্করণটি দিচ্ছেন না" আমার সি ++ এর আমার সংস্করণটি আমার প্রশ্নের সাথে সম্পর্কিত নয়। "সুতরাং পুরো প্রোগ্রামটির বিবৃতিটি যে কোনও কিছু করতে পারে" আমি জানি, তবে আমার প্রশ্নটি ছিল নির্দিষ্ট আচরণ সম্পর্কে। "আপনার মন্তব্য সেখানে উত্তরের সামগ্রী প্রতিফলিত করে না।" আমার মন্তব্যটি আমার প্রশ্নের বিষয়বস্তুকে প্রতিফলিত করে, যা আপনার পুনরায় পড়া উচিত।
দারুচিনি

4
শিরোনামের উত্তর দিতে; কারণ ইউবি মানে বাহাভিওর অনির্ধারিত। ইতিহাসের বিভিন্ন সময়ে বিভিন্ন সময়ে তৈরি একাধিক সংকলক, বিভিন্ন আর্কিটেকচারের জন্য বিভিন্ন ব্যক্তি দ্বারা, যখন লাইনের বাইরে রঙিন করতে এবং সত্যিকারের বাস্তবায়ন করতে বলা হয় তাদের নির্দিষ্টকরণের বাইরে এই অংশে কিছু রাখতে হয়েছিল, তাই লোকেরা ঠিক সেটাই করেছিল এবং প্রতিটি তাদের মধ্যে বিভিন্ন ক্রাইওন ব্যবহৃত হয়েছিল। অতএব হোয়রি ম্যাক্সিম, ইউবি
টবি

উত্তর:


199

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

কোড

int i = 1;
int x = ++i + ++i;

নিম্নলিখিত নির্দেশাবলী নিয়ে গঠিত:

1. store 1 in i
2. read i as tmp1
3. add 1 to tmp1
4. store tmp1 in i
5. read i as tmp2
6. read i as tmp3
7. add 1 to tmp3
8. store tmp3 in i
9. read i as tmp4
10. add tmp2 and tmp4, as tmp5
11. store tmp5 in x

তবে এটি আমি যেভাবে লিখেছি তার তালিকাভুক্ত হওয়া সত্ত্বেও এখানে কয়েকটি অর্ডিং নির্ভরতা রয়েছে: 1-> 2-> 3-> 4-> 5-> 10-> 11 এবং 1-> 6-> 7- > 8-> 9-> 10-> 11 অবশ্যই তাদের আপেক্ষিক ক্রমে থাকা উচিত। এর বাইরে অন্য সংকলকটি অবাধে পুনঃক্রম করতে পারে, এবং সম্ভবত অপ্রয়োজনীয়তা দূর করে।

উদাহরণস্বরূপ, আপনি এই তালিকার অর্ডার করতে পারেন:

1. store 1 in i
2. read i as tmp1
6. read i as tmp3
3. add 1 to tmp1
7. add 1 to tmp3
4. store tmp1 in i
8. store tmp3 in i
5. read i as tmp2
9. read i as tmp4
10. add tmp2 and tmp4, as tmp5
11. store tmp5 in x

সংকলক কেন এটি করতে পারে? কারণ বর্ধনের পার্শ্ব প্রতিক্রিয়াগুলির কোনও অনুক্রম নেই। তবে এখন সংকলকটি সহজ করতে পারে: উদাহরণস্বরূপ, 4-এ একটি ডেড স্টোর রয়েছে: মান অবিলম্বে ওভাররাইট করা হবে। এছাড়াও, tmp2 এবং tmp4 আসলে একই জিনিস।

1. store 1 in i
2. read i as tmp1
6. read i as tmp3
3. add 1 to tmp1
7. add 1 to tmp3
8. store tmp3 in i
5. read i as tmp2
10. add tmp2 and tmp2, as tmp5
11. store tmp5 in x

এবং এখন tmp1 এর সাথে করার সমস্ত কিছুই ডেড কোড: এটি কখনই ব্যবহৃত হয় না। এবং আমার পুনরায় পড়ার বিষয়টিও দূর করা যেতে পারে:

1. store 1 in i
6. read i as tmp3
7. add 1 to tmp3
8. store tmp3 in i
10. add tmp3 and tmp3, as tmp5
11. store tmp5 in x

দেখুন, এই কোডটি আরও খাটো। অপটিমাইজার খুশি। প্রোগ্রামারটি নয়, কারণ আমি কেবল একবারই বৃদ্ধি পেয়েছিলাম। উফ!

এর পরিবর্তে সংকলক আর কিছু করতে পারে তা দেখুন: আসল সংস্করণে ফিরে আসি।

1. store 1 in i
2. read i as tmp1
3. add 1 to tmp1
4. store tmp1 in i
5. read i as tmp2
6. read i as tmp3
7. add 1 to tmp3
8. store tmp3 in i
9. read i as tmp4
10. add tmp2 and tmp4, as tmp5
11. store tmp5 in x

সংকলক এটি এটিকে পুনরায় অর্ডার করতে পারে:

1. store 1 in i
2. read i as tmp1
3. add 1 to tmp1
4. store tmp1 in i
6. read i as tmp3
7. add 1 to tmp3
8. store tmp3 in i
5. read i as tmp2
9. read i as tmp4
10. add tmp2 and tmp4, as tmp5
11. store tmp5 in x

এবং তারপরে আবার লক্ষ্য করুন যে আমি দুবার পড়ছি, সুতরাং তাদের মধ্যে একটি মুছে ফেলুন:

1. store 1 in i
2. read i as tmp1
3. add 1 to tmp1
4. store tmp1 in i
6. read i as tmp3
7. add 1 to tmp3
8. store tmp3 in i
5. read i as tmp2
10. add tmp2 and tmp2, as tmp5
11. store tmp5 in x

এটি দুর্দান্ত, তবে এটি আরও এগিয়ে যেতে পারে: এটি tmp1 পুনরায় ব্যবহার করতে পারে:

1. store 1 in i
2. read i as tmp1
3. add 1 to tmp1
4. store tmp1 in i
6. read i as tmp1
7. add 1 to tmp1
8. store tmp1 in i
5. read i as tmp2
10. add tmp2 and tmp2, as tmp5
11. store tmp5 in x

তারপরে এটি 6 এ i এর পুনরায় পঠনটি দূর করতে পারে:

1. store 1 in i
2. read i as tmp1
3. add 1 to tmp1
4. store tmp1 in i
7. add 1 to tmp1
8. store tmp1 in i
5. read i as tmp2
10. add tmp2 and tmp2, as tmp5
11. store tmp5 in x

এখন 4 একটি ডেড স্টোর:

1. store 1 in i
2. read i as tmp1
3. add 1 to tmp1
7. add 1 to tmp1
8. store tmp1 in i
5. read i as tmp2
10. add tmp2 and tmp2, as tmp5
11. store tmp5 in x

এবং এখন 3 এবং 7 এক নির্দেশে একত্রীকরণ করা যেতে পারে:

1. store 1 in i
2. read i as tmp1
3+7. add 2 to tmp1
8. store tmp1 in i
5. read i as tmp2
10. add tmp2 and tmp2, as tmp5
11. store tmp5 in x

শেষ অস্থায়ী অপসারণ:

1. store 1 in i
2. read i as tmp1
3+7. add 2 to tmp1
8. store tmp1 in i
10. add tmp1 and tmp1, as tmp5
11. store tmp5 in x

এবং এখন আপনি ভিজুয়াল সি ++ আপনাকে যে ফলাফল দিচ্ছেন তা পেয়েছেন।

নোট করুন যে উভয় অপটিমাইজেশন পাথে, গুরুত্বপূর্ণ ক্রমের নির্ভরতাগুলি সংরক্ষণ করা হয়েছিল, কারণ কিছুই করার জন্য নির্দেশাবলী সরানো হয়নি।


36
বর্তমানে, এটি একমাত্র উত্তর যা ক্রমক্রমের উল্লেখ করেছে ।
প্রধানমন্ত্রী 2Ring

4
-1 আমি মনে করি না যে এই উত্তরটি স্পষ্ট করছে। পর্যবেক্ষণের ফলাফলগুলি কোনও সংকলক অপ্টিমাইজেশনের উপর নির্ভর করে না (আমার উত্তর দেখুন)।
ড্যানিয়েল আর কলিন্স

4
এটি রিড-মডিফাই-রাইটিং অপারেশন ধরে নিয়েছে। কিছু সিপিইউ, যেমন সর্বব্যাপী x86 এর একটি পারমাণবিক বর্ধন অপারেশন রয়েছে, যা পরিস্থিতির আরও জটিলতা যুক্ত করে।
চিহ্নিত করুন

6
@ ফিলিপ্সি "স্ট্যান্ডার্ডটির অবজেক্ট কোড সম্পর্কে কিছু বলার নেই।" এই স্নিপেটের আচরণ সম্পর্কে স্ট্যান্ডার্ডটির কিছুই বলার নেই - এটি ইউবি। এটা প্রশ্নের একটি ভিত্তি। ওপি জানতে চেয়েছিল কেন, বাস্তবে, সংকলকগণ বিভিন্ন এবং অদ্ভুত ফলাফলের দিকে আসতে পারে। এছাড়াও, আমার উত্তর এমনকি অবজেক্ট কোড সম্পর্কে কিছু বলে না।
সেবাস্তিয়ান রেডল

4
@ ফিলিপ্সি আমি আপনার আপত্তি বুঝতে পারি না। উল্লিখিত হিসাবে, প্রশ্নটি একটি সংকলক ইউবির উপস্থিতিতে কী করতে পারে তা নয়, সি ++ স্ট্যান্ডার্ড সম্পর্কে নয়। অনুমানমূলক সংকলক কোডটি কীভাবে রূপান্তর করছে তা অন্বেষণ করার সময় কেন অবজেক্ট কোড ব্যবহার করা অনুচিত হবে? আসলে, কীভাবে অবজেক্ট কোড ছাড়া অন্য কিছু প্রাসঙ্গিক হতে পারে?
কনরাড রুডলফ

58

যদিও এটি ইউবি (ওপি সূচিত হিসাবে), নিম্নলিখিতটি অনুমানমূলক পদ্ধতিগুলি সহ একটি সংকলক 3 ফলাফল পেতে পারে। তিনটিই এক এবং একই পরিবর্তে xবিভিন্ন int i = 1, j = 1;ভেরিয়েবলের সাথে ব্যবহার করা হলে একই সঠিক ফলাফল দেবে i

  1. উভয় ++ আমি 2 ফেরত, যার ফলে x = 4 হয়।
int i = 1;
int i1 = i, i2 = i;   // i1 = i2 = 1
++i1;                 // i1 = 2
++i2;                 // i2 = 2
int x = i1 + i2;      // x = 4
  1. এক ++ আমি 2 এবং অন্যটি 3 প্রদান করে, যার ফলে x = 5 হয়।
int i = 1;
int i1 = ++i;           // i1 = 2
int i2 = ++i;           // i2 = 3
int x = i1 + i2;        // x = 5
  1. উভয় ++ আমি 3 ফেরান, এর ফলে x = 6।
int i = 1;
int &i1 = i, &i2 = i;
++i1;                   // i = 2
++i2;                   // i = 3
int x = i1 + i2;        // x = 6

4
আমি যা আশা করি তার থেকে এটি একটি ভাল প্রতিক্রিয়া, আপনাকে ধন্যবাদ।
দারুচিনি

4
বিকল্প 1 এর জন্য, সংকলকটি প্রাকপরিমাণে একটি নোট তৈরি করেছে i। এটি একবারে ঘটতে পারে তা জেনে এটি কেবল একবারই প্রেরণ করে। বিকল্প 2 এর জন্য কোডটি আক্ষরিকভাবে মেশিন কোডে অনুবাদ করা হয়েছে যেমন কোনও কলেজ সংকলক শ্রেণীর প্রকল্প পারে। বিকল্প 3 এর জন্য, এটি বিকল্প 1 এর মতো, তবে এটি প্রিনক্রেনমেন্টের দুটি অনুলিপি তৈরি করেছে। একটি ভেক্টর অবশ্যই ব্যবহার করা উচিত, সেট নয়। :-)
Zan Lynx

@ ডেক্সিভ দুঃখিত, আমার খারাপ, আমি পোস্টগুলি মিশিয়েছি
মুরু

22

আমার কাছে, দ্বিতীয়টি সম্ভবত খুব সম্ভবত বলে মনে হচ্ছে।

আমি # 4 বিকল্পের জন্য যাচ্ছি: উভয়ই ++iএকই সাথে ঘটে।

আরও নতুন প্রসেসরগুলি কিছু আকর্ষণীয় অপ্টিমাইজেশান এবং সমান্তরাল কোড মূল্যায়নের দিকে অগ্রসর হয়, যেখানে এখানে যেমন অনুমতি দেওয়া হয়েছে, কম্পাইলাররা দ্রুত কোড তৈরি করা অন্য উপায় another আমি ব্যবহারিক বাস্তবায়ন হিসাবে দেখছি , সংকলক সমান্তরালতার দিকে এগিয়ে চলেছেন।

একই ধরণের স্মৃতিবিরোধের কারণে আমি অঘোষিত আচরণ বা বাসের ত্রুটির কারণে সহজেই দৌড়ের অবস্থা দেখতে পেলাম - কোডার সি ++ চুক্তি লঙ্ঘন করায় সবই অনুমোদিত - সুতরাং ইউবি।

আমার প্রশ্ন: একটি সি ++ সংকলক কী (যুক্তিসঙ্গত) জিনিসগুলি করতে পারে যা 4 বা ফলাফল বা 6 বা ফলাফলের দিকে পরিচালিত করতে পারে?

এটি পারে , কিন্তু এটিতে গণনা করবেন না।

++i + ++iবোধগম্য ফলাফল ব্যবহার বা আশা করবেন না ।


আমি যদি এই উত্তর এবং @ dxiv উভয়ই গ্রহণ করতে পারি I প্রতিক্রিয়ার জন্য আপনাকে ধন্যবাদ.
দারুচিনি

4
@ উরিয়াজ: প্রসেসরটি হয়ত খেয়ালও করতে পারে না যে সংকলকের পছন্দ অনুসারে কোনও ডেটা বিপত্তি রয়েছে। উদাহরণস্বরূপ সংকলকটি iদুটি নিবন্ধকে বরাদ্দ করতে পারে , উভয় নিবন্ধকেই বৃদ্ধি করতে পারে এবং উভয়কেই আবার লিখতে পারে। প্রসেসরের এটি সমাধানের কোনও উপায় নেই। মূল সমস্যাটি হ'ল সি ++ বা আধুনিক সিপিইউ উভয়ই কঠোরভাবে অনুক্রমিক নয়। সি ++ এর স্পষ্টতই ঘটেছিল আগে-ঘটে যাওয়া এবং পরে-সিকোয়েন্সিংয়ের পরে, একই সাথে একই সময়ে ডিফল্টরূপে ঘটে যায়।
এমসাল্টারস

4
তবে আমরা জানি যে ভিজ্যুয়াল স্টুডিও ব্যবহার করে ওপি-র ক্ষেত্রে এটি হয় না; x86 এবং এআরএম সহ বেশিরভাগ মূলধারার আইএসএগুলি কার্যকরভাবে সম্পূর্ণরূপে অনুক্রমের মডেল হিসাবে সংজ্ঞায়িত হয় যেখানে একটি মেশিন নির্দেশ পরেরটি শুরু হওয়ার আগে সম্পূর্ণভাবে শেষ হয়। অফ-অর্ডার সুপারসকালার অবশ্যই একক থ্রেডের জন্য সেই মায়া বজায় রাখতে হবে। (ভাগ করা মেমরি পড়ার অন্যান্য থ্রেডগুলি প্রোগ্রাম ক্রমে জিনিসগুলি দেখার গ্যারান্টিযুক্ত নয়, তবে ওও এক্সিকিউটিভের মূল নিয়মটি একক থ্রেডেড এক্সিকিউশনটি ভাঙ্গার নয়))
পিটার কর্ডেস

4
এটি আমার প্রিয় উত্তর, কারণ এটিই কেবলমাত্র সিপিইউ স্তরে সমান্তরাল নির্দেশনা কার্যকরকরণের উল্লেখ করে। বিটিডব্লু, উত্তরে উত্তরে উল্লেখ করতে হবে যে, বর্ণের অবস্থার কারণে সিপিইউ থ্রেড একই মেমরির অবস্থানটিতে একটি মুটেক্স আনলকের জন্য অপেক্ষা করা বন্ধ হয়ে থাকবে, সুতরাং এটি সম্মতিযুক্ত মডেলটিতে অত্যন্ত অস্বাভাবিক। দ্বিতীয় - একই বর্ণের শর্তের কারণে আসল উত্তরটি হতে পারে 4বা 5, - সিপিইউ থ্রেড এক্সিকিউশন মডেল / গতির উপর নির্ভর করে, তাই এটি হৃদপিণ্ডের ইউবি B
অগ্নিওস ভ্যাসিলিয়াসকাস

4
@ অ্যাগনিয়াস ভ্যাসিলিয়াসকাস সম্ভবত, এখনও "বাস্তবে, কেন বিভিন্ন সংকলক বিভিন্ন মান গণনা করবে" আজকের প্রসেসরের সরল দৃষ্টিভঙ্গি দেওয়া সহজ বোঝার জন্য আরও বেশি খুঁজছেন। তবুও কয়েকটি বিভিন্ন উত্তর বর্ণিত সংখ্যার চেয়ে অনেক বেশি সংকলক / প্রসেসরের দৃশ্যের পরিসীমা। আপনার দরকারী অন্তর্দৃষ্টি অন্য এক। আইএমও, সমান্তরালতা হ'ল ভবিষ্যত এবং সুতরাং এই উত্তরটি তাদের উপর দৃষ্টি নিবদ্ধ রেখেছিল, যদিও একটি বিমূর্ত পদ্ধতিতে - যদিও ভবিষ্যতে এখনও উদ্ঘাটিত হচ্ছে। আইএসি, পোস্টটি জনপ্রিয় হয়ে উঠেছে এবং উত্তরগুলি সহজেই উপলব্ধি করা সেরা পুরষ্কার প্রাপ্ত।
chux - মনিকা পুনরায় ইনস্টল করুন

17

আমি মনে করি যে একটি সহজ এবং সরল ব্যাখ্যা (সংকলনের অপ্টিমাইজেশান বা মাল্টিথ্রেডিংয়ের কোনও বিড ছাড়াই) ন্যায়সঙ্গত হবে:

  1. বৃদ্ধি i
  2. বৃদ্ধি i
  3. যোগ করুন i+i

iদুবার বর্ধিত হওয়ার সাথে সাথে এর মান 3, এবং যখন একত্রে যুক্ত হয়, যোগফল 6 হয়।

পরিদর্শন করার জন্য, এটি সি ++ ফাংশন হিসাবে বিবেচনা করুন:

int dblInc ()
{
    int i = 1;
    int x = ++i + ++i;
    return x;   
}

এখন, জিএনইউ সি ++ সংকলক (উইন 32, জিসিসি সংস্করণ 3.4.2 (মিংডাব্লু-স্পেশাল)) এর একটি পুরানো সংস্করণ ব্যবহার করে function ফাংশনটি সংকলন করে আমি এখানে এসেম্বলি কোডটি পেয়েছি। এখানে কোনও অভিনব অপ্টিমাইজেশন বা মাল্টিথ্রেডিং ঘটেনি:

__Z6dblIncv:
    push    ebp
    mov ebp, esp
    sub esp, 8
    mov DWORD PTR [ebp-4], 1
    lea eax, [ebp-4]
    inc DWORD PTR [eax]
    lea eax, [ebp-4]
    inc DWORD PTR [eax]
    mov eax, DWORD PTR [ebp-4]
    add eax, DWORD PTR [ebp-4]
    mov DWORD PTR [ebp-8], eax
    mov eax, DWORD PTR [ebp-8]
    leave
    ret

নোট করুন যে স্থানীয় ভেরিয়েবল iকেবল একটি একক জায়গায় স্ট্যাকের উপর বসে আছে: ঠিকানা [ebp-4]। এই অবস্থানটি দু'বার বাড়ানো হয়েছে (বিধানসভা অনুষ্ঠানের 5 ম-8 তম লাইনে; স্পষ্টতই সেই ঠিকানাটির অতিরিক্ত অপ্রয়োজনীয় লোড সহ eax)। তারপরে নবম-দশম লাইনে, সেই মানটি লোড করা হয় eaxএবং তারপরে যুক্ত করা হয় eax(এটি বর্তমানের গণনা করে i + i)। তারপরে এটি অনিয়মিতভাবে স্ট্যাকের অনুলিপি করা হয়েছে এবং eaxফেরতের মান হিসাবে ফিরে আসবে (যা স্পষ্টতই 6 হবে)।

সি ++ স্ট্যান্ডার্ডটি দেখার জন্য এটি আগ্রহী হতে পারে (এখানে একটি পুরানো: আইএসও / আইইসি 14882: 1998 (ই)) যা এক্সপ্রেশনগুলির জন্য বলে, বিভাগ 5.4:

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

পাদটীকা সহ:

অপারেটরগুলির নজির সরাসরি নির্দিষ্ট করা হয়নি তবে এটি সিনট্যাক্স থেকে নেওয়া যেতে পারে।

অনির্দিষ্ট আচরণের দুটি উদাহরণ সেই সময়ে দেওয়া হয়, উভয়ই ইনক্রিমেন্ট অপারেটরকে জড়িত (যার মধ্যে একটি i = ++i + 1:) :

এখন, যদি কেউ ইচ্ছা করেন তবে একজন এটি করতে পারেন: একটি পূর্ণসংখ্যার মোড়কের ক্লাস তৈরি করুন (জাভা ইন্টিজারের মতো); ওভারলোড ফাংশন operator+এবং operator++এগুলি যে তারা মধ্যবর্তী মান বস্তুগুলি ফেরত দেয়; এবং তারপরে এটি লিখুন ++iObj + ++iObjএবং এটি একটি অবজেক্ট 5 ধারণ করে ফিরিয়ে আনুন ((আমি ব্রিভিটির জন্য এখানে পুরো কোডটি অন্তর্ভুক্ত করি নি))

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


4
বর্ধনকারী অপারেটরটির সত্যিকার অর্থে খুব ভাল সংজ্ঞা দেওয়া "রিটার্ন" মান রয়েছে
edc65

@ ফিলিপ্সি: আপনি যে প্যাসেজগুলিতে আপত্তি করেছেন তা উত্তোলনের জন্য আমি উত্তরটি সম্পাদনা করেছি। আপনি এই মুহুর্তে উত্তরটির সাথে আরও একমত হতে পারেন বা নাও করতে পারেন।
ড্যানিয়েল আর কলিন্স

4
এগুলি "অনির্ধারিত আচরণের দুটি উদাহরণ" নয়, সেগুলি স্ট্যান্ডার্ডের অন্য এক উত্তরণ থেকে উদ্ভূত এক অপরিজ্ঞিত আচরণের দুটি উদাহরণ different আমি দেখতে পাই যে সি ++ 98 পাদটীকা উদাহরণের পাঠ্যটিতে "অনির্দিষ্ট" বলা হত, আদর্শ পাঠ্যের বিপরীতে, তবে এটি পরে স্থির হয়েছিল।
চবি

@ কুবিবি: এখানে উদ্ধৃত স্ট্যান্ডার্ডের পাঠ্য এবং পাদটীকা উভয়ই "অনির্দিষ্ট", "সরাসরি নির্দিষ্ট নয়" বাক্যাংশটি ব্যবহার করেছেন এবং এটি সংজ্ঞাটি বিভাগ ১.৩.১৩ এর সাথে মিল রয়েছে বলে মনে হয় to
ড্যানিয়েল আর কলিন্স

4
@ ফিলিপ্সি: আমি দেখতে পাচ্ছি যে আপনি এখানে অনেক উত্তরের জন্য একই মন্তব্যটি পুনরাবৃত্তি করেছেন। দেখে মনে হচ্ছে আপনার মূল সমালোচক নিজেই ওপি-র প্রশ্ন সম্পর্কে আরও বেশি, যার সুযোগটি কেবল বিমূর্ত মান সম্পর্কে নয়।
ড্যানিয়েল আর কলিন্স

7

একটি সংকলক যে যুক্তিসঙ্গত জিনিসটি করতে পারে তা হ'ল সাধারণ সুব্রপ্রেসন ইলিমিনেশন। এটি ইতিমধ্যে সংকলকগুলিতে একটি সাধারণ অপ্টিমাইজেশন: (x+1)বৃহত্তর এক্সপ্রেশনে যদি একটির মতো এক্সপ্রেসশন একাধিকবার ঘটে থাকে তবে এটি কেবল একবার গণনা করা দরকার। মধ্যে যেমন উপ-অভিব্যক্তি একবার গণনা করা যেতে পারে।a/(x+1) + b*(x+1)x+1

অবশ্যই, সংকলকটি জানতে হবে যে উপ-এক্সপ্রেশনগুলি সেভাবে অনুকূলিত হতে পারে। rand()দুবার কল করার জন্য দুটি এলোমেলো নম্বর দেওয়া উচিত। ইন-ইনলাইনড ফাংশন কলগুলি অবশ্যই সিএসই থেকে অব্যাহতিপ্রাপ্ত হতে হবে। আপনারা যেমন খেয়াল করেছেন, এমন কোনও নিয়ম নেই যা বলে যে দুটি ঘটনা কীভাবে i++পরিচালনা করা উচিত, সুতরাং সেগুলি সিএসই থেকে ছাড় দেওয়ার কোনও কারণ নেই।

ফলস্বরূপ হতে পারে যে int x = ++i + ++i;অনুকূলিত হয় int __cse = i++; int x = __cse << 1। (সিএসই, পুনরাবৃত্তি শক্তি হ্রাস দ্বারা অনুসরণ)


স্ট্যান্ডার্ডটির অবজেক্ট কোড সম্পর্কে কিছু বলার নেই। এটি ভাষা সংজ্ঞা দ্বারা ন্যায়সঙ্গত বা সম্পর্কিত নয়।
ফিলিপ্সি

4
@ ফিলিপ্সি: স্ট্যান্ডার্ডটির কোনও অপরিবর্তিত আচরণের কোনও রূপ সম্পর্কে কিছু বলার নেই। এটাই প্রশ্নের ভিত্তি।
এমসাল্টারস

7

অনুশীলনে, আপনি অনির্ধারিত আচরণটি চালাচ্ছেন। যেকোনো কিছু ঘটতে পারে, শুধু যে আপনি বিবেচনা "যুক্তিযুক্ত", এবং প্রায়ই কিছু না ঘটতে যে আপনার যুক্তিসংগত মনে করি না। সবকিছুই "যুক্তিসঙ্গত" সংজ্ঞা অনুসারে হয়।

একটি খুব যুক্তিসঙ্গত সংকলন হ'ল সংকলকটি পর্যবেক্ষণ করে যে একটি বিবৃতি কার্যকর করা অনির্ধারিত আচরণের ডাক দেয়, সুতরাং বিবৃতিটি কার্যকর করা যায় না, সুতরাং এটি এমন একটি নির্দেশে অনুবাদ করা হয়েছে যা ইচ্ছাকৃতভাবে আপনার অ্যাপ্লিকেশনটিকে ক্র্যাশ করে। এটা খুব যুক্তিসঙ্গত।

ডাউনভোটার: জিসিসি আপনার সাথে দৃ strongly়ভাবে একমত নয়।


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

6

কোনও সংকলক 6 এর ফলাফল পেতে পারে এমন কোনও যুক্তিসঙ্গত জিনিস নেই , তবে এটি সম্ভব এবং বৈধ। 4 এর ফলাফল সম্পূর্ণ যুক্তিসঙ্গত, এবং আমি 5 টি সীমান্তরেখার যুক্তিসঙ্গত বিবেচনা করব। এগুলির সবই পুরোপুরি আইনী।

অপেক্ষা কর! কি হবে তা পরিষ্কার নয়? সংযোজনটির দুটি বর্ধনের ফলাফলের প্রয়োজন, সুতরাং অবশ্যই এগুলি প্রথমে ঘটতে হবে। এবং আমরা বাম থেকে ডানে যেতে পারি, সুতরাং ... আরগ! যদি এটি এত সহজ ছিল। দুর্ভাগ্যক্রমে, এটি কেস নয়। আমরা বাম থেকে ডানে যাব না , এবং এটিই সমস্যা।

দুটি রেজিস্টারে মেমরির অবস্থানটি পড়া (বা উভয়টিকে একই আক্ষরিক থেকে শুরু করে, মেমোরিতে রাউন্ড ট্রিপটি অনুকূল করে তোলা) সংকলকটির পক্ষে করা খুব যুক্তিসঙ্গত জিনিস। এটি গোপনে দুটি পৃথক ভেরিয়েবলের প্রভাব ফেলবে , যার মধ্যে 2 টির মান রয়েছে যা শেষ পর্যন্ত 4 এর ফলাফলের সাথে যুক্ত হবে এটি "যুক্তিসঙ্গত" কারণ এটি দ্রুত এবং দক্ষ, এবং এটি উভয়ের সাথে সামঞ্জস্যপূর্ণ মান এবং কোড সহ।

একইভাবে, মেমরির অবস্থানটি একবার পড়তে পারে (বা আক্ষরিক থেকে চলকটি আরম্ভ করা হয়েছিল) এবং একবারে বাড়ানো যেতে পারে এবং অন্য রেজিস্টারে একটি ছায়া অনুলিপি তার পরে বাড়ানো যেতে পারে, যার ফলে 2 এবং 3 একসাথে যুক্ত হয়ে যায়। এটি আমি বলব সীমান্ত যুক্তিযুক্ত, যদিও পুরোপুরি আইনী। আমি এটিকে সীমান্ত যুক্তিযুক্ত বলে মনে করি কারণ এটি এক বা অন্য নয়। এটি না "যুক্তিসঙ্গত" অনুকূলিত উপায়, না এটি "যুক্তিসঙ্গত" হুবহু পেডেন্টিক উপায় নয়। এটি কিছুটা মাঝখানে।

মেমরির অবস্থান দু'বার বাড়ানো (যার ফলে 3 টির মান হয়) এবং তারপরে 6 এর চূড়ান্ত ফলাফলের জন্য নিজের কাছে সেই মান যুক্ত করা বৈধ, তবে মেমরির রাউন্ড ট্রিপগুলি করা মোটেই কার্যকর নয়। যদিও ভাল স্টোর ফরোয়ার্ডিং সহ প্রসেসরের উপর, এটি করাও "যুক্তিসঙ্গত" হতে পারে, যেহেতু স্টোরটি বেশিরভাগ অদৃশ্য হওয়া উচিত ...
সংকলকটি "জানে" যে এটি একই অবস্থান হিসাবে, এটি পাশাপাশি বৃদ্ধিও পছন্দ করতে পারে একটি রেজিস্টার এর মধ্যে দুবার মান, এবং তারপরে এটি নিজেই যুক্ত করুন। হয় পদ্ধতির আপনি 6 ফলাফল দিতে হবে।

সংকলকটি স্ট্যান্ডার্ডের কথাটি বলে আপনাকে এ জাতীয় কোনও ফল দেওয়ার অনুমতি দেয়, যদিও আমি ব্যক্তিগতভাবে no জনকে অপ্রত্যাশিত বিভাগের একটি "ফাক ইউ" স্মৃতি হিসাবে বিবেচনা করব, কারণ এটি একটি বরং অপ্রত্যাশিত জিনিস (আইনী বা না, সর্বদা সর্বনিম্ন চমক দেওয়ার চেষ্টা করা ভাল কাজ!)। যদিও, অপরিজ্ঞিত আচরণটি কীভাবে জড়িত তা দেখে, দুঃখের সাথে সত্যই কেউ "অপ্রত্যাশিত" সম্পর্কে তর্ক করতে পারেন না, হ্যাঁ।

সুতরাং, আসলে, সংকলকটিতে আপনার এখানে কোডটি কী? আসুন ঝাঁকুনি জিজ্ঞাসা করুন, যা আমরা যদি সুন্দরভাবে জিজ্ঞাসা করি (আমাদের সাথে কথা বলি) তা আমাদের দেখায় -ast-dump -fsyntax-only:

ast.cpp:4:9: warning: multiple unsequenced modifications to 'i' [-Wunsequenced]
int x = ++i + ++i;
        ^     ~~
(some lines omitted)
`-CompoundStmt 0x2b3e628 <line:2:1, line:5:1>
  |-DeclStmt 0x2b3e4b8 <line:3:1, col:10>
  | `-VarDecl 0x2b3e430 <col:1, col:9> col:5 used i 'int' cinit
  |   `-IntegerLiteral 0x2b3e498 <col:9> 'int' 1
  `-DeclStmt 0x2b3e610 <line:4:1, col:18>
    `-VarDecl 0x2b3e4e8 <col:1, col:17> col:5 x 'int' cinit
      `-BinaryOperator 0x2b3e5f0 <col:9, col:17> 'int' '+'
        |-ImplicitCastExpr 0x2b3e5c0 <col:9, col:11> 'int' <LValueToRValue>
        | `-UnaryOperator 0x2b3e570 <col:9, col:11> 'int' lvalue prefix '++'
        |   `-DeclRefExpr 0x2b3e550 <col:11> 'int' lvalue Var 0x2b3e430 'i' 'int'
        `-ImplicitCastExpr 0x2b3e5d8 <col:15, col:17> 'int' <LValueToRValue>
          `-UnaryOperator 0x2b3e5a8 <col:15, col:17> 'int' lvalue prefix '++'
            `-DeclRefExpr 0x2b3e588 <col:17> 'int' lvalue Var 0x2b3e430 'i' 'int'

আপনি দেখতে পাচ্ছেন, একই দুটি lvalue Var 0x2b3e430উপস্থায় উপসর্গ ++প্রয়োগ হয়েছে, এবং এই দুটি গাছের একই নোডের নীচে রয়েছে, যা খুব অ-বিশেষ অপারেটর (+) হিসাবে দেখা যায় যা সিকোয়েন্সিং বা এ জাতীয় সম্পর্কে বিশেষ কিছু বলা হয় নি। এটা জরুরী কেন? ভাল, পড়ুন।

সতর্কবার্তাটি নোট করুন: "'i' তে একাধিক অব্যক্ত পরিবর্তনসমূহ" । ওহ ওহ, এটি ভাল শোনাচ্ছে না। এর মানে কী? [বেসেল.এক্সেক] আমাদের পার্শ্ব প্রতিক্রিয়া এবং সিকোয়েন্সিং সম্পর্কে জানায় এবং এটি আমাদেরকে (অনুচ্ছেদ 10) বলে যে ডিফল্টরূপে অন্যথায় স্পষ্টভাবে বলা না হলে পৃথক অপারেটরগুলির ক্রিয়াকলাপগুলির মূল্যায়ন এবং স্বতন্ত্র এক্সপ্রেশনগুলির সুস্পষ্ট এক্সেসেন্সিয়েন্স হয় না । হ্যাঁ, হ্যাঁ, এই ক্ষেত্রে এটি operator+- অন্যথায় কিছুই বলা হচ্ছে না, তাই ...

তবে আমরা কি সিকোয়েন্সড-এর আগে, অনির্দিষ্টভাবে-সিক্যুয়েন্সড, বা অনির্ধারিত সম্পর্কে যত্নশীল? কে জানতে চায়, যাইহোক?

সেই একই অনুচ্ছেদটি আমাদের এও বলেছে যে অমীমাংসিত মূল্যায়নগুলি ওভারল্যাপ হতে পারে এবং যখন তারা একই মেমরি অবস্থানটি উল্লেখ করে (এটিই কেস!) এবং যেটি সম্ভাব্যভাবে একত্রে না হয়, তখন আচরণটি অনির্ধারিত হয়। এটি এখানেই সত্যই কুৎসিত হয় কারণ এর অর্থ আপনি কিছুই জানেন না এবং যা কিছু "যুক্তিসঙ্গত" হওয়ার কোনও গ্যারান্টি নেই। অযৌক্তিক জিনিসটি আসলে নিখুঁতভাবে অনুমোদিত এবং "যুক্তিসঙ্গত"।


"যুক্তিসঙ্গত" এর ব্যবহার কেবলমাত্র "সংকলক কিছু করতে পারে এমনকী, এমনকি একক নির্দেশ 'x x থেকে 7' নির্গত করতে পারে তা বলতে বাধা দেওয়ার জন্যই সম্ভবত আমার স্পষ্ট করা উচিত ছিল।
দারুচিনি

@ দারুচিনি বহু বছর আগে, যখন আমি অল্প বয়স্ক এবং অনভিজ্ঞ ছিলাম, সনের সংকলক ইঞ্জিনিয়াররা আমাকে বলেছিলেন যে তাদের সংকলকটি অপরিজ্ঞাত আচরণের জন্য একেবারে যুক্তিসঙ্গত উত্পাদন কোডের অভিনয় করেছিল যেটি আমি তখন অযৌক্তিক বলে মনে করি। পাঠ শিখেছি।
gnasher729

স্ট্যান্ডার্ডটির অবজেক্ট কোড সম্পর্কে কিছু বলার নেই। আপনার প্রস্তাবিত বাস্তবায়নগুলি কীভাবে ভাষার সংজ্ঞা দ্বারা যুক্তিযুক্ত বা সম্পর্কিত বলে এটি খণ্ডিত ও অস্পষ্ট।
ফিলিপ্সি

@ ফিলিপ্সি: স্ট্যান্ডার্ডটি সংজ্ঞায়িত করে যে কোনটি সুগঠিত এবং সু-সংজ্ঞায়িত এবং কী নয়। এই প্রশ্নটির ক্ষেত্রে এটি আচরণকে সংজ্ঞায়িত হিসাবে সংজ্ঞায়িত করে। আইনী হওয়ার বাইরেও, কার্যকর কোড তৈরির সংকলকগুলির যুক্তিসঙ্গত অনুমানও রয়েছে। হ্যাঁ, আপনি ঠিক বলেছেন, মানকটিকে এমনটি হওয়ার দরকার নেই। তা সত্ত্বেও এটি একটি যুক্তিসঙ্গত অনুমান।
দামোন

1

একটি নিয়ম আছে :

পূর্ববর্তী এবং পরবর্তী সিকোয়েন্স পয়েন্টের মধ্যে একটি স্কেলার অবজেক্টের অবশ্যই তার সঞ্চিত মানটি একবারে প্রকাশের মূল্যায়নের মাধ্যমে একবারে পরিবর্তিত হওয়া উচিত, অন্যথায় আচরণটি সংজ্ঞায়িত।

সুতরাং এমনকি x = 100 একটি সম্ভাব্য বৈধ ফলাফল।

আমার জন্য উদাহরণটির মধ্যে সবচেয়ে যুক্তিসঙ্গত ফলাফল 6, কারণ আমরা দু'বার i এর মান বাড়িয়ে দিচ্ছি এবং সেগুলি এটি নিজের সাথে যুক্ত করে। "+" উভয় পক্ষের গণনা মানগুলির পূর্বে যোগ করা কঠিন।

তবে সংকলক বিকাশকারীরা অন্য যে কোনও যুক্তি প্রয়োগ করতে পারবেন।


0

দেখে মনে হচ্ছে যে ++ আমি একটি কদর দেয় তবে আমি ++ একটি মূল্য দেয়।
সুতরাং এই কোড ঠিক আছে:

int i = 1;
++i = 10;
cout << i << endl;

এটি একটি নয়:

int i = 1;
i++ = 10;
cout << i << endl;

উপরের দুটি বিবৃতি ভিজ্যুয়ালসি ++, জিসিসি 7.1.1, ক্লাং এবং এমবারকাডেরোর সাথে সামঞ্জস্যপূর্ণ।
এজন্য আপনার ভিজ্যুয়ালসি ++ এবং জিসিসি 7.1.1 এ থাকা কোডটি নিম্নলিখিত একটির মতো

int i = 1;
... do something there for instance: ++i; ++i; ...
int x = i + i;

বিচ্ছিন্নতার দিকে তাকানোর সময়, এটি প্রথমে i, পুনর্লিখন i বৃদ্ধি করে। এটি যুক্ত করার চেষ্টা করার সময় একই জিনিসটি হয়, আমিবৃদ্ধি করে এটি আবার লিখি। তারপরে i তে যোগ করুন। আমি লক্ষ্য করেছি ক্লাং এবং এমবারকাডেরো ভিন্নভাবে কাজ করে। সুতরাং এটি প্রথম বিবৃতিটির সাথে সামঞ্জস্যপূর্ণ নয়, প্রথম ++ পরে এটি ফলাফলকে একটি মূল্যায়ণে সংরক্ষণ করে এবং তারপরে এটি দ্বিতীয় আই ++ এ যুক্ত করে।
এখানে চিত্র বর্ণনা লিখুন


"দেখায় একটি লভ্যালু দেখায়" সমস্যাটি হ'ল আপনি কোনও সংকলক নয়, সি ++ স্ট্যান্ডার্ডের দৃষ্টিকোণ থেকে কথা বলছেন।
এমসাল্টারস

@ এসএমএলটাররা বিবৃতিটি ভিজ্যুয়াল স্টুডিও 2019, জিসিসি 7.1.1, ঝনঝন এবং এম্বারকাডেরো এবং কোডের প্রথম অংশের সাথে সামঞ্জস্যপূর্ণ। স্পেসিফিকেশন তাই সামঞ্জস্যপূর্ণ। তবে এটি দ্বিতীয় পিসের কোডের জন্য আলাদাভাবে কাজ করে। কোডের দ্বিতীয় অংশটি ভিজ্যুয়াল স্টুডিও 2019 এবং জিসিসি 7.1.1 এর সাথে সামঞ্জস্যপূর্ণ তবে ঝনঝন এবং এম্বারকাডেরোর সাথে সামঞ্জস্য নয়।
আর্মাজেডেস্কু

4
ঠিক আছে, আপনার উত্তরে কোডের প্রথম অংশটি আইনী সি ++, সুতরাং স্পষ্টতই বাস্তবায়নগুলি নির্দিষ্টকরণের সাথে সামঞ্জস্যপূর্ণ the প্রশ্নের তুলনায় আপনার "কিছু করুন" একটি অর্ধপরিমাণে শেষ হয়, এটি একটি সম্পূর্ণ বিবৃতি দেয়। এটি একটি সিকোয়েন্সিং তৈরি করে যা সি ++ মানক দ্বারা প্রয়োজনীয়, তবে প্রশ্নের মধ্যে উপস্থিত নেই।
এমসাল্টারস

@ এসএমএলটাররা আমি এটি একটি সমতুল্য সিউডো কোড হিসাবে করতে চেয়েছিলাম। তবুও আমি কীভাবে এটি সংশোধন করতে পারছি তা নিশ্চিত নই
আর্মেজেডকু

0

আমি ব্যক্তিগতভাবে কখনই আপনার উদাহরণে 6 টি আউটপুট সংগ্রহ করার আশা করিনি। ইতিমধ্যে আপনার প্রশ্নের ভাল এবং বিস্তারিত উত্তর রয়েছে। আমি একটি সংক্ষিপ্ত সংস্করণ চেষ্টা করব।

মূলত, ++iএই প্রসঙ্গে একটি 2-পদক্ষেপ প্রক্রিয়া:

  1. এর মান বৃদ্ধি করা i
  2. মান পড়ুন i

++i + ++iসংযোজনের দুটি পক্ষের প্রেক্ষিতে মান অনুযায়ী কোনও ক্রমে মূল্যায়ন করা যেতে পারে। এর অর্থ এই দুটি ইনক্রিমেন্টকে স্বতন্ত্র বিবেচনা করা হয়। এছাড়াও, দুটি পদটির মধ্যে কোনও নির্ভরতা নেই। এর ইনক্রিমেন্ট এবং পঠন iআন্তঃবাহিত হতে পারে। এটি সম্ভাব্য আদেশ দেয়:

  1. iবাম অপারেন্ডের জন্য বৃদ্ধি
  2. iডান অপরেন্ডের জন্য বৃদ্ধি
  3. iবাম অপারেন্ডের জন্য ফিরে পড়ুন
  4. iডান অপারেন্ডের জন্য ফিরে পড়ুন
  5. দুটি যোগফল: ফলন 6

এখন, যে আমি এটি সম্পর্কে চিন্তা করি, 6 মান অনুসারে সর্বাধিক বোধ করে। 4 এর ফলাফলের জন্য আমাদের একটি সিপিইউ দরকার যা প্রথমে iস্বতন্ত্রভাবে পড়ে , তারপরে ইনক্রিমেন্ট এবং মানটি একই স্থানে লেখে; মূলত একটি জাতি শর্ত। 5 এর মানের জন্য আমাদের একটি সংকলক প্রয়োজন যা অস্থায়ীগুলির পরিচয় করিয়ে দেয়।

তবে, স্ট্যান্ডার্ডটি বলে যে ++iভেরিয়েবলটি ফিরিয়ে দেওয়ার আগে অর্থাৎ প্রকৃতপক্ষে বর্তমান কোড লাইনটি কার্যকর করার আগে ইনক্রিমেন্ট। ইনক্রিমেন্ট প্রয়োগের পরে যোগ অপারেটরের যোগফল +প্রয়োজন i + i। আমি বলব যে সি ++ এর ভেরিয়েবলগুলির উপর কাজ করা দরকার, কোনও মান শব্দার্থক নয়। সুতরাং, আমার কাছে 6 এখন সর্বাধিক অর্থবোধ করে কারণ এটি ভাষার শব্দার্থবিজ্ঞানের উপর নির্ভর করে না সিপিইউগুলির কার্যনির্বাহনের মডেল।


0
#include <stdio.h>


void a1(void)
{
    int i = 1;
    int x = ++i;
    printf("i=%d\n",i);
    printf("x=%d\n",x);
    x = x + ++i;    // Here
    printf("i=%d\n",i);
    printf("x=%d\n",x);
}


void b2(void)
{
    int i = 1;
    int x = ++i;
    printf("i=%d\n",i);
    printf("x=%d\n",x);
    x = i + ++i;    // Here
    printf("i=%d\n",i);
    printf("x=%d\n",x);
}


void main(void)
{
    a1();
    // b2();
}

স্ট্যাকওভারফ্লোতে স্বাগতম! আপনি আপনার উত্তরে যে কোনও সীমাবদ্ধতা, অনুমান বা সরলীকরণ সরবরাহ করতে পারেন। এই লিঙ্কটিতে কীভাবে উত্তর দেবেন সে সম্পর্কে আরও বিশদটি দেখুন: stackoverflow.com/help/how-to-answer
উসামা আব্দুলরেহমান

0

এটি সংকলনের ডিজাইনের উপর নির্ভর করে। সুতরাং সংকলক যেভাবে বিবৃতিগুলি ডিকোড করে তার উপর উত্তর নির্ভর করবে a যুক্তি তৈরির পরিবর্তে দুটি ভিন্ন ভেরিয়েবল ++ x এবং ++ y ব্যবহার করা আরও ভাল পছন্দ হবে। দ্রষ্টব্য: আউটপুটটি যদি আপডেট হয় তবে এমএস ভিজ্যুয়াল স্টুডিওতে ভাষার সর্বশেষ সংস্করণটির উপর নির্ভর করে the


0

এটা চেষ্টা কর

int i = 1;
int i1 = i, i2 = i;   // i1 = i2 = 1
++i1;                 // i1 = 2
++i2;                 // i2 = 2
int x = i1 + i2;      // x = 4

-4

অনুশীলনে, আপনি অনির্ধারিত আচরণটি চালাচ্ছেন। যেকোনো কিছু ঘটতে পারে, শুধু যে আপনি বিবেচনা "যুক্তিযুক্ত", এবং প্রায়ই কিছু না ঘটতে যে আপনার যুক্তিসংগত মনে করি না। সবকিছুই "যুক্তিসঙ্গত" সংজ্ঞা অনুসারে।

একটি খুব যুক্তিসঙ্গত সংকলন হ'ল সংকলকটি পর্যবেক্ষণ করে যে একটি বিবৃতি কার্যকর করা অনির্ধারিত আচরণকে ডেকে আনে, সুতরাং বিবৃতিটি কখনও কার্যকর করা যায় না, সুতরাং এটি এমন নির্দেশে অনুবাদ করা হয়েছে যা ইচ্ছাকৃতভাবে আপনার অ্যাপ্লিকেশনটিকে ক্র্যাশ করে। এটা খুব যুক্তিসঙ্গত। সর্বোপরি, সংকলক জানে যে এই ক্রাশ কখনই ঘটতে পারে না।


4
আমি বিশ্বাস করি আপনি প্রশ্নটি ভুল বুঝেছেন। প্রশ্নটি সাধারণ বা নির্দিষ্ট আচরণ সম্পর্কে যা নির্দিষ্ট ফলাফলের দিকে নিয়ে যেতে পারে (x = 4, 5 বা 6 এর ফলাফল)। আপনি যদি আমার "যুক্তিসঙ্গত" শব্দের ব্যবহার পছন্দ না করেন তবে আমি আপনাকে উপরের আমার মন্তব্যে পরিচালিত করব, যার জবাব আপনি দিয়েছিলেন: "'যুক্তিসঙ্গত' ব্যবহারটি কাউকে এই কথা বলতে বিরত করার জন্যই ছিল 'সংকলক কিছু করতে পারে না, এমনকি একক নির্দেশ '' x x থেকে 7 সেট নির্গত করুন mit '' "" আপনার যদি সাধারণ ধারণাটি ধরে রাখে এমন প্রশ্নের পক্ষে যদি আরও ভাল শব্দ থাকে তবে আমি এটির জন্য উন্মুক্ত। এছাড়াও, মনে হয় আপনি নিজের উত্তরটি পুনরায় পোস্ট করেছেন।
দারুচিনি

4
আপনার দুটি উত্তর একটি মুছে ফেলার পরামর্শ দিন যেহেতু সেগুলি উভয়ই একই রকম
এমএম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.