সি = ++ (এ + বি) সংকলন ত্রুটি কেন দেয়?


111

গবেষণা করার পরে, আমি পড়লাম যে ইনক্রিমেন্ট অপারেটরের অপারেন্ডকে একটি পরিবর্তনযোগ্য ডেটা অবজেক্ট থাকতে হবে: https://en.wikedia.org/wiki/Increment_and_decrement_operators

এ থেকে আমি অনুমান করি যে এটি সংকলন ত্রুটি দেয় কারণ (a+b)একটি অস্থায়ী পূর্ণসংখ্যা এবং তাই পরিবর্তনযোগ্য নয়।

এই বোঝার কি সঠিক? সমস্যাটি নিয়ে গবেষণা করার চেষ্টা করা আমার এই প্রথম সময় ছিল তাই যদি আমার এমন কিছু হয় তবে দয়া করে পরামর্শ দেওয়ার চেষ্টা করা উচিত।


35
এটি গবেষণার দিক থেকে খারাপ নয়। তুমি কি সঠিক পথে আছো.
গল্পগ্রাহক - আনস্ল্যান্ডার মনিকা

35
আপনি এক্সপ্রেশনটি কী করবেন বলে আশা করছেন?
qrdl

4
সি 11 স্ট্যান্ডার্ড অনুসারে 6.5.3.1: উপসর্গের বৃদ্ধি বা হ্রাস অপারেটরের পারমাণবিক, যোগ্য, বা অযোগ্য সত্য বা পয়েন্টার টাইপ থাকবে এবং একটি পরিবর্তনযোগ্য মূল্য হবে
খ্রিস্টান গিবনস

10
আপনি কীভাবে পছন্দ করেন যে 1 টি a এবং b এর মধ্যে বিতরণ করা হবে? "অ্যারে সূচকগুলি কি 0 বা 1 থেকে শুরু করা উচিত? আমার 0.5% এর আপসটি যথাযথ বিবেচনা না করেই প্রত্যাখ্যান করা হয়েছিল।" - স্ট্যান কেলি-বুটল
অ্যান্ড্রু মর্টন

5
আমি মনে করি যে প্রশ্নে একটি অনুসরণ তা হ'ল কেন আপনি কখনই এটি করতে চান যখন c = a + b + 1আপনার অভিপ্রায়কে আরও স্পষ্ট করা হয় এবং টাইপ করা আরও ছোট হয়। ইনক্রিমেন্ট / হ্রাস অপারেটর দুটি কাজ করে 1. তারা এবং তাদের যুক্তি একটি অভিব্যক্তি গঠন করে (এটি ব্যবহার করা যেতে পারে, উদাহরণস্বরূপ লুপের জন্য), ২. তারা যুক্তি পরিবর্তন করে। আপনার উদাহরণে আপনি সম্পত্তি 1 ব্যবহার করছেন তবে সম্পত্তি 2 নয়, কারণ আপনি পরিবর্তিত যুক্তিটি ফেলে দেন। যদি আপনার 2 সম্পত্তি প্রয়োজন না হয় এবং কেবল এক্সপ্রেশন চান তবে আপনি কেবল একটি এক্সপ্রেশন লিখতে পারেন, যেমন x ++ এর পরিবর্তে x + 1।
ট্রেভর

উত্তর:


117

এটি কেবল একটি নিয়ম, এগুলিই এবং এটি সম্ভবত রয়েছে (1) সি সংকলকগুলি লিখতে সহজ করে তোলে এবং (2) সি স্ট্যান্ডার্ড কমিটিটিকে শিথিল করার পক্ষে কেউ বিশ্বাস করেনি।

অনানুষ্ঠানিকভাবে বলতে গেলে আপনি কেবল তখনই লিখতে ++fooপারেন যদি fooকোনও অ্যাসাইনমেন্টের মত প্রকাশের বাম দিকে উপস্থিত হতে পারে foo = bar। যেহেতু আপনি লিখতে a + b = barপারবেন না তাই আপনিও লিখতে পারবেন ++(a + b)না।

কোনও a + bঅস্থায়ী ফল কেন না পারে যার ++কোন কাজ করতে পারে তার কোন আসল কারণ নেই এবং এর ফলাফলটিই হ'ল অভিব্যক্তির মান ++(a + b)


4
আমি মনে করি পয়েন্ট (1) মাথায় পেরেক আঘাত করে। কেবলমাত্র C ++ এ অস্থায়ী বস্তুকরণের জন্য নিয়মগুলি দেখলে যে কারওর পেটে পরিণত হতে পারে (তবে এটি শক্তিশালী, যদিও তা বলতে হবে)।
স্টোরি টেলার - আনস্ল্যান্ডার মনিকা

4
@ স্টিরিটেলার: সত্যই, আমাদের প্রিয় ভাষা সি ++ এর বিপরীতে সি এখনও অপেক্ষাকৃত তুচ্ছভাবে সমাবেশে সংকলন করে।
বাথশেবা

29
এখানে একটি আসল কারণ আইএমএইচও: এটি কোনও ভয়ঙ্কর বিভ্রান্তি হতে পারে যদি ++কখনও কখনও কোনও কিছু সংশোধন করার পার্শ্ব প্রতিক্রিয়া থাকে এবং কখনও কখনও তা না ঘটে।
aschepler

5
@ ডিএনজি: আসলে এটি; এই কারণেই লভালু এবং মূল্যমান পদগুলি চালু করা হয়েছিল যদিও বর্তমানেকার বিষয়গুলি আরও জটিল (বিশেষত সি ++ তে)। উদাহরণস্বরূপ, একটি ধ্রুবক কখনই মূল্যবান হতে পারে না: 5 = a এর মতো কিছু বুদ্ধি করে না।
বাথশেবা

6
@ বাথশেবা এটি ব্যাখ্যা করে যে কেন 5++ সংকলনের ত্রুটির কারণ করে
Dng

40

সি 11 স্ট্যান্ডার্ড বিভাগ 6.5.3.1

প্রিফিক্স ইনক্রিমেন্ট বা হ্রাস অপারেটরের অপারেন্ডের পারমাণবিক, যোগ্য, বা অযোগ্য রিয়েল বা পয়েন্টার টাইপ থাকবে এবং এটি একটি পরিবর্তনযোগ্য মূল্য হবে

এবং "সংশোধনযোগ্য লভ্যালু" বিভাগ 6.3.2.1 উপধারা 1 এ বর্ণিত হয়েছে

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

সুতরাং (a+b)কোনও পরিবর্তনযোগ্য লভ্যালু নয় এবং তাই উপসর্গ ইনক্রিমেন্ট অপারেটরের জন্য যোগ্য নয় eligible


1
এই সংজ্ঞাগুলি থেকে আপনার উপসংহারটি অনুপস্থিত ... আপনি বলতে চান যে (a + b) কোনও বস্তুটি সম্ভাব্যভাবে নির্দিষ্ট করে না, তবে এই অনুচ্ছেদগুলি এটির অনুমতি দেয় না।
এইচকেবিস্ট

21

আপনি সঠিক. ++মূল পরিবর্তনশীল নতুন মান নির্ধারণ করার চেষ্টা করে। সুতরাং ++aএর মান গ্রহণ করবে a, এতে যুক্ত 1হবে এবং তারপরে এটিকে পুনরায় নির্ধারণ করুন a। যেহেতু, আপনি যেমন বলেছেন, (a + b) একটি সাময়িক মান, এবং নির্ধারিত মেমরি ঠিকানার কোনও ভেরিয়েবল নয়, কার্য সম্পাদন করা যায় না।


12

আমি মনে করি আপনি বেশিরভাগ নিজের প্রশ্নের উত্তর দিয়েছেন। আমি আপনার ফ্রেসিংয়ে সামান্য পরিবর্তন আনতে পারি এবং সিগিবনের উল্লেখ অনুসারে "অস্থায়ী পরিবর্তনশীল "টিকে" মূল্য "দিয়ে প্রতিস্থাপন করতে পারি।

ভেরিয়েবল, আর্গুমেন্ট, অস্থায়ী পরিবর্তনশীল এবং এই জাতীয় শর্তাদি আরও স্পষ্ট হয়ে উঠবে যখন আপনি সি এর মেমোরি মডেল সম্পর্কে শিখবেন (এটি দেখতে একটি দুর্দান্ত ওভারভিউ: https://www.geeksforgeeks.org/memory-layout-of-c-program/ )।

"মূল্য" শব্দটি অস্বচ্ছ মনে হতে পারে যখন আপনি সবে শুরু করছেন, সুতরাং আমি আশা করি নিম্নলিখিতটি এটি সম্পর্কে একটি স্বজ্ঞাততা বিকাশে সহায়তা করে।

সমান চিহ্ন (অ্যাসাইনমেন্ট অপারেটর) এর বিভিন্ন পক্ষের বিষয়ে লভালু / রালুয়ে কথা বলছে: লভালু = বাম হাতের দিক (ছোট হাতের এল, "একটি" নয়) মূল্য = ডানদিকে

সি কীভাবে মেমোরি ব্যবহার করে (এবং রেজিস্ট্রেশনগুলি) সে সম্পর্কে কিছুটা জানতে পার্থক্যটি কেন গুরুত্বপূর্ণ তা দেখার জন্য সহায়ক হবে। ইন বিস্তৃত বুরুশ স্ট্রোক , কম্পাইলার একটি অভিব্যক্তি (rvalue) ফল গনা যে মেশিন ভাষা নির্দেশাবলী একটি তালিকা তৈরি করে এবং তারপর রাখে যে ফলাফলের কোথাও (lvalue)। নিম্নলিখিত কোড টুকরা সঙ্গে কাজ করে একটি সংকলক কল্পনা করুন:

x = y * 3

সমাবেশ pseudocode মধ্যে এটি পারে এই খেলনা উদাহরণের মত চেহারা:

load register A with the value at memory address y
load register B with a value of 3
multiply register A and B, saving the result in A
write register A to memory address x

++ অপারেটর (এবং এর - সমকক্ষ) এর পরিবর্তিত করতে একটি "কোথাও" দরকার, মূলত যে কোনও কিছু যা মূল্য হিসাবে কাজ করতে পারে।

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

ঠিক একদিকে যেমন: ++ নির্দেশনাটি ১৯69৯ সাল থেকে প্রায় শুরু হয়েছে (যদিও এটি সি এর পূর্বসূরি বিতে শুরু হয়েছিল):

(কেন থম্পসনের) পর্যবেক্ষণ (ছিল) যে ++ এক্স এর অনুবাদ x = x + 1 এর চেয়ে ছোট ছিল। "

উইকিপিডিয়া রেফারেন্সটি অনুসরণ করা আপনাকে সুবিধার্থে এখানে লিঙ্কিত ডানিস রিচি ("কেএন্ডআর সি" তে "আর") র একটি আকর্ষণীয় লিখনআপে নিয়ে যাবে: http://www.bell-labs.com/ usr / dmr / www / chist.html যেখানে আপনি "++" অনুসন্ধান করতে পারেন।


6

কারণটি হ'ল মানকটির অপারেন্ডটি একটি লভ্যালু হওয়া প্রয়োজন। অভিব্যক্তিটি (a+b)কোনও মূল্য নয়, সুতরাং বর্ধিত অপারেটর প্রয়োগের অনুমতি নেই।

এখন, কেউ বলতে পারে "ঠিক আছে, এটাই আসলে কারণ, তবে প্রকৃতপক্ষে এর ব্যতীত অন্য কোন আসল * কারণ নেই" , তবে দুর্ভাগ্যক্রমে অপারেটর কীভাবে কার্যত কাজ করে তার নির্দিষ্ট শব্দটির ক্ষেত্রে এটি হওয়া দরকার require

এক্সপ্রেশন ++ E সমান (E + = 1)।

স্পষ্টতই, আপনি E += 1যদি Eলভ্যালু না হন তবে লিখতে পারবেন না । যা একটি লজ্জাজনক কারণ একজন ঠিক যেমনটি বলতে পেরেছিলেন: "ইনক্রিমেন্ট ই এক করে" এবং করা যায়। সেক্ষেত্রে সংযোজকটিকে কিছুটা জটিল করে তোলার ব্যয়ে নন-লভ্যালুতে অপারেটরটি প্রয়োগ করা (নীতিগতভাবে) পুরোপুরি সম্ভব হবে।

এখন, সংজ্ঞাটি তুচ্ছভাবে বর্ণিত হতে পারে (আমি মনে করি এটি মূলত সি নয় তবে খ এর উত্তরাধিকারী), তবে এটি করার ফলে ভাষা মৌলিকভাবে এমন কিছুতে পরিবর্তিত হবে যা এর আগের সংস্করণগুলির সাথে সামঞ্জস্য নয়। যেহেতু সম্ভাব্য উপকারটি বরং সামান্য তবে সম্ভাব্য প্রভাবগুলি বিশাল, যা কখনও ঘটেনি এবং সম্ভবত কখনও ঘটবে না।

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



3

++ মূল ভেরিয়েবলকে মান দেওয়ার চেষ্টা করে এবং যেহেতু (a + b) একটি সাময়িক মান এটি অপারেশন করতে পারে না। এবং এগুলি মূলত প্রোগ্রামিং সহজ করার জন্য সি প্রোগ্রামিং কনভেনশনের নিয়ম। এটাই.


2

যখন ++ (a + b) এক্সপ্রেশনটি সম্পাদিত হয়, তারপরে উদাহরণস্বরূপ:

int a, b;
a = 10;
b = 20;
/* NOTE :
 //step 1: expression need to solve first to perform ++ operation over operand
   ++ ( exp );
// in your case 
   ++ ( 10 + 20 );
// step 2: result of that inc by one 
   ++ ( 30 );
// here, you're applying ++ operator over constant value and it's invalid use of ++ operator 
*/
++(a+b);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.