বিবৃতি কেন ছিল (জে ++); নিষিদ্ধ?


169

নিম্নলিখিত কোডটি ভুল (এটি আদর্শে দেখুন ):

public class Test
{
    public static void Main()
    {
        int j = 5;
        (j++);      // if we remove the "(" and ")" then this compiles fine.
    }
}

ত্রুটি CS0201: কেবলমাত্র অ্যাসাইনমেন্ট, কল, ইনক্রিমেন্ট, হ্রাস, প্রতীক্ষা এবং নতুন অবজেক্ট এক্সপ্রেশন একটি বিবৃতি হিসাবে ব্যবহার করা যেতে পারে

  1. আমরা যখন প্রথম বন্ধনী সরিয়ে দিই তখন কোড কেন সংকলন করে?
  2. কেন এটি প্রথম বন্ধনীর সাথে সংকলন করে না?
  3. সি # কেন সেভাবে ডিজাইন করা হয়েছিল?

29
@ সি # ভাষা নকশার সাথে জড়িত প্রচুর লোক এসও তে আছেন, সুতরাং আমি কেন জিজ্ঞাসা করেছি তা ঠিক। এর সাথে কিছু ভুল?
ব্যবহারকারীর 10607

34
"একটি নির্দিষ্ট প্রোগ্রামিং ভাষা কেন এই পদ্ধতিতে এই নির্দিষ্ট আচরণটি পরিচালনা করে?" এর চেয়ে বেশি বিষয় নিয়ে আমি কল্পনাও করতে পারি না?
ম্যাজ জাই

20
এখন আমাদের কাছে এরিক লিপার্টের একটি উত্তর আছে। সম্ভবত আপনি গৃহীত উত্তর সম্পর্কে আপনার সিদ্ধান্তটি পুনরায় চিন্তা করতে চান। এটি বড়দিন, তাই সম্ভবত আপনি উত্তরটি খুব তাড়াতাড়ি গ্রহণ করেছেন।
টমাস ওয়েলার

17
@ সার্ভে আপনি কি বোঝাচ্ছেন যে ডিজাইনের সিদ্ধান্তগুলি কখনই নথিভুক্ত হয় না এবং অন্য সবার কাছে একেবারেই অজানা? তিনি এসও ব্যবহারকারীদের অনুমান করতে বলছেন না , তিনি একটি উত্তর চাইছেন - এটি বোঝায় না যে তিনি অনুমানের জন্য জিজ্ঞাসা করছেন। লোকেরা অনুমান দিয়ে উত্তর দেয় কিনা তা চালু আছে তাদের , তাকে নয়। এবং হিসাবে ওপি নির্দিষ্ট, সেখানে হয় যারা স্ট্যাক ওভারফ্লো মানুষের করেনি আসলে C # এর কাজ এবং এই সিদ্ধান্ত।
রব

5
@ রব: সমস্যাটি হ'ল, হ্যাঁ, যদি না যুক্তিটি ইতিমধ্যে অন্য কোথাও নথিভুক্ত না করা হয় তবে অবশ্যই অনুমান করা যায়, তবে জল্পনা মজাদার এবং কে তার নিজের ভাগ করে নিতে চায় না? যদি আপনি নিশ্চিত হয়ে থাকেন যে এই জাতীয় খাঁটি (বা "শিক্ষিত") অনুমানগুলি নির্ভরযোগ্যভাবে শেষ হয়েছে তবে আমাকে বলুন এবং আমরা একটি ভাগ্য তৈরি করব।
Deduplicator

উত্তর:


221

গভীর অন্তর্দৃষ্টি প্রশংসা।

আমি আমার যথাসাধ্য চেষ্টা করব

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

পয়েন্ট হ'ল: কেবলমাত্র অভিব্যক্তি নিয়ে গঠিত বিবৃতিগুলি অবশ্যই ত্রুটিযুক্ত না হয় যদি না এই অভিব্যক্তিগুলি সাধারণত তাদের মানগুলির চেয়ে পার্শ্ব প্রতিক্রিয়াগুলির জন্য আরও কার্যকর হিসাবে বিবেচিত হয় । সি # ডিজাইনাররা সাধারণত তাদের পার্শ্বপ্রতিক্রিয়া হিসাবে বিবেচিত এমন অভিব্যক্তিগুলিকে মঞ্জুরি দিয়ে মধ্যবর্তী স্থল খুঁজে পেতে ইচ্ছুক ছিলেন, যখন সাধারণত তাদের মূল্যবোধের জন্য দরকারী হিসাবে বিবেচিত হয় তাদের এড়িয়ে যান। সি # 1.0 এ তারা প্রকাশের সেটটি হ'ল ইনক্রিমেন্ট, হ্রাস, পদ্ধতি কল, অ্যাসাইনমেন্ট এবং কিছুটা বিতর্কিতভাবে, নির্মাণকারীর অনুরোধ।


সংযুক্তি: একজন সাধারণভাবে কোনও অবজেক্ট কনস্ট্রাকশনকে এটির মান হিসাবে উত্পাদন হিসাবে বিবেচনা করে বলে মনে করেন, নির্মাণের পার্শ্ব প্রতিক্রিয়ার জন্য নয়; আমার মতে অনুমতি দেওয়া new Foo();হ'ল কিছুটা ভুল ধারণা fe বিশেষত, আমি এই প্যাটার্নটি বাস্তব-বিশ্বের কোডে দেখেছি যা একটি সুরক্ষা ত্রুটির কারণ হয়েছিল:

catch(FooException ex) { new BarException(ex); } 

কোডটি জটিল হলে এই ত্রুটিটি চিহ্নিত করা আশ্চর্যরকম কঠিন হতে পারে।


সংকলক অতএব সেই সমস্ত বিবৃতি সনাক্ত করতে কাজ করে যা সেই তালিকায় নেই এমন অভিব্যক্তিগুলি নিয়ে গঠিত। বিশেষত, প্রথম বন্ধনীযুক্ত এক্সপ্রেশনগুলি ঠিক সেইরূপেই চিহ্নিত করা হয় - প্রথম বন্ধনীযুক্ত এক্সপ্রেশন। তারা "বিবৃতি প্রকাশ হিসাবে অনুমোদিত" এর তালিকায় নেই, তাই তাদের অনুমতি দেওয়া হয়নি।

এই সমস্তগুলি সি # ভাষার একটি ডিজাইনের নীতিমালার পরিষেবাতে রয়েছে। আপনি যদি টাইপ করেন তবে (x++);আপনি সম্ভবত কিছু ভুল করছেন । এটি সম্ভবত একটি টাইপো M(x++);বা কিছু সাধারণ জিনিস। মনে রাখবেন, সি # সংকলক দলের মনোভাব " মনোভাবটি " এই কাজটি করার জন্য আমরা কী কোনও উপায় বের করতে পারি ? " সি # সংকলক দলের মনোভাবটি " যদি সম্ভাবনাময় কোডটি সম্ভবত কোনও ভুল বলে মনে হয় তবে আসুন আমরা বিকাশকারীকে অবহিত করি "। সি # বিকাশকারীদের এই মনোভাবের মতো।

এখন, সমস্ত যা বলেছে, সেখানে আসলে কয়েকটি অদ্ভুত ঘটনা রয়েছে যেখানে সি # নির্দিষ্টকরণ রয়েছে না পরোক্ষভাবে বা রাজ্য সরাসরি যে প্রথম বন্ধনী অননুমোদিত হয় কিন্তু C # এর কম্পাইলার তাদের কোন পথে পারেন। প্রায় সমস্ত ক্ষেত্রেই নির্দিষ্ট আচরণ এবং অনুমোদিত আচরণের মধ্যে সামান্য তাত্পর্য পুরোপুরি নিরীহ, সুতরাং সংকলক লেখকরা এই ছোট বাগগুলি কখনই স্থির করেননি। আপনি এখানে তাদের সম্পর্কে পড়তে পারেন:

রিটার্ন মাইওয়ার বনাম রিটার্ন (মাইভার) এর মধ্যে কি পার্থক্য রয়েছে?


5
পুনরায়: "একজন সাধারণভাবে একজন নির্মাণকারীর অনুরোধকে এটির মান হিসাবে নির্মিত হিসাবে ব্যবহার করে, নির্মাণের পার্শ্ব প্রতিক্রিয়ার জন্য নয় বলে মনে করেন; আমার মতে এটি কিছুটা ভুল ধারণা": আমি এই সিদ্ধান্তের একটি কারণটি কল্পনা করতে পারি ছিল যে যদি কম্পাইলার এটা forbade, মামলা আছে যেখানে আপনি যে কোন পরিষ্কার ফিক্স হবে না হয় একটি পার্শ্ব-প্রভাবের জন্য এটি আহ্বান। (বেশিরভাগ অন্যান্য নিষিদ্ধ অভিব্যক্তি বিবৃতিতে বহিরাগত অংশ রয়েছে যা কোনও উদ্দেশ্য করে না এবং ... ? ... : ...ifelse
এটির

1
@রুখ: যেহেতু এটি এমন আচরণ যা নিরুৎসাহিত করা উচিত, তাই পরিষ্কার-পরিচ্ছন্নতা প্রয়োজনীয় নয়, যতক্ষণ না যুক্তিসঙ্গতভাবে সস্তা / সরল ফিক্স রয়েছে। যা আছে; এটি একটি ভেরিয়েবলের জন্য বরাদ্দ করুন এবং সেই পরিবর্তনশীলটি ব্যবহার করবেন না। আপনি যদি এটি নির্মমভাবে বলতে চান যে আপনি এটি ব্যবহার করছেন না, তবে কোডটির লাইনটিকে তার নিজস্ব সুযোগ দিন। যদিও প্রযুক্তিগতভাবে কেউ তর্ক করতে পারে যে এটি কোডের শব্দার্থবিজ্ঞানের পরিবর্তন করে (একটি অকেজো রেফারেন্স অ্যাসাইনমেন্ট এখনও একটি অকেজো রেফারেন্স অ্যাসাইনমেন্ট), বাস্তবে এটি বিবেচনার সম্ভাবনা কম। আমি স্বীকার করি যে এটি কিছুটা আলাদা আইএল তৈরি করে ... তবে কেবল অপটিমাইজেশন ছাড়াই সংকলন করা হয়।
ব্রায়ান

টাইপ করার সময় সাফারি, ফায়ারফক্স এবং ক্রোম সমস্তই রেফারেন্সইরর দেয় contineu;
ব্রায়ান ম্যাকচ্যাটন

2
@ এমসি ব্রেনি: আপনি ঠিক বলেছেন। আমি ভুল ত্রুটি থেকে ভুলত্রুটি করছি যা ভুল বানান থেকে প্রাপ্ত হয়; আমি আমার নোট চেক করব। এরই মধ্যে আমি আপত্তিজনক বক্তব্যটি মুছে ফেলেছি কারণ এটি এখানে বৃহত পয়েন্টের কাছে জার্মান নয়।
এরিক লিপার্ট

1
@ মাইক: আমি সম্মত আরেকটি পরিস্থিতি যেখানে আমরা মাঝে মাঝে বিবৃতিটি দেখতে পাই তা পরীক্ষার ক্ষেত্রে যেমন হয় try { new Foo(null); } catch (ArgumentNullException)...তবে স্পষ্টতই এই পরিস্থিতিগুলি সংজ্ঞা অনুসারে উত্পাদন কোড নয়। এটি যুক্তিসঙ্গত বলে মনে হয় যে এই জাতীয় কোডটি একটি ডামি ভেরিয়েবলকে বরাদ্দ করার জন্য রচনা করা যেতে পারে।
এরিক লিপার্ট

46

ইন সি # ভাষা স্পেসিফিকেশন

এক্সপ্রেশন বিবৃতি এক্সপ্রেশন মূল্যায়ন করতে ব্যবহৃত হয়। বিবৃতি হিসাবে ব্যবহার করা যেতে পারে যে অভিব্যক্তিগুলির মধ্যে পদ্ধতি আহ্বান, নতুন অপারেটর ব্যবহার করে অবজেক্ট বরাদ্দ, = এবং যৌগিক অ্যাসাইনমেন্ট অপারেটরগুলি ব্যবহার করে, ++ এবং - অপারেটরগুলি ব্যবহার করে ইনক্রিমেন্ট এবং হ্রাস অপারেশন এবং এক্সপ্রেশনগুলির জন্য অপেক্ষা করা অন্তর্ভুক্ত রয়েছে।

একটি স্টেটমেন্টের চারপাশে বন্ধনী স্থাপন করা একটি নতুন তথাকথিত প্রথম বন্ধনী প্রকাশ করে। স্পেসিফিকেশন থেকে:

একটি প্রথম বন্ধনীযুক্ত-এক্সপ্রেশনটি একটি বন্ধনীতে আবদ্ধ একটি অভিব্যক্তি নিয়ে গঠিত। ... একটি প্রথম বন্ধনীযুক্ত-এক্সপ্রেশনটি প্রথম বন্ধনীগুলির মধ্যে প্রকাশের মূল্যায়ন করে মূল্যায়ন করা হয়। বন্ধনীগুলির মধ্যে প্রকাশ যদি কোনও নামস্থান বা প্রকারকে বোঝায় তবে একটি সংকলন-সময় ত্রুটি ঘটে। অন্যথায়, বন্ধুত্বপূর্ণ-এক্সপ্রেশন ফলাফলটি অন্তর্ভুক্ত প্রকাশের মূল্যায়নের ফলাফল।

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


4
@ সার্ভে: আপনি যদি নিবিড়ভাবে পড়েন তবে এটি তার চেয়ে কিছুটা বেশি প্রয়োজন ছিল। তথাকথিত "এক্সপ্রেশন বিবৃতি" প্রকৃতপক্ষে একটি বৈধ বিবৃতি, এবং স্পেসিফিকেশনটি এমন ধরণের অভিব্যক্তিগুলির তালিকাবদ্ধ করে যা বৈধ বিবৃতি হতে পারে। তবে, আমি সেই অনুমান থেকে পুনরুক্তি করি যে "প্যারেন্থাইজড এক্সপ্রেশন" নামক অভিব্যক্তিটির বৈধ এক্সপ্রেশনগুলির তালিকায় নেই যা বৈধ অভিব্যক্তি বিবৃতি হিসাবে ব্যবহার করা যেতে পারে।
ফ্র্যাঙ্ক ব্রাইস

4
OPভাষা ডিজাইন সম্পর্কে কিছুই জানতে চাইছে। তিনি কেবল এটি কেন ত্রুটি তা জানতে চান। উত্তরটি হ'ল: কারণ এটি বৈধ বিবৃতি নয়
লিয়ান্ড্রো

9
ঠিক আছে, আমার খারাপ। উত্তরটি হ'ল: কারণ, স্পেসিফিকেশন অনুসারে , এটি কোনও বৈধ বিবৃতি নয়। সেখানে আপনার এটি রয়েছে: একটি নকশার কারণ!
লিয়ান্ড্রো

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

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

19

কাছাকাছি বন্ধনী বোকা i++ একটি অভিব্যক্তি তৈরি / সংজ্ঞায়িত করছে .. ত্রুটি বার্তাটি যেমন বলেছে .. একটি সাধারণ অভিব্যক্তি স্টেটমেন্ট হিসাবে ব্যবহার করা যায় না।

ভাষাটি কেন এভাবে ডিজাইন করা হয়েছিল? বাগ আটকাতে, বিবৃতি হিসাবে বিভ্রান্তিমূলক অভিব্যক্তি থাকা, যা কোড থাকার মতো কোনও পার্শ্ব প্রতিক্রিয়া তৈরি করে না

int j = 5;
j+1; 

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

সম্পাদনা করুন :

অংশটিকে আরও স্পষ্ট করার জন্য .. সি # তে বন্ধনী (অন্যান্য ব্যবহারগুলি ছাড়াও, কাস্ট এবং ফাংশন কল হিসাবে) গ্রুপের মত প্রকাশের জন্য ব্যবহৃত হয় এবং একটি একক অভিব্যক্তি ফিরে আসে (সাব এক্সপ্রেশনগুলি তৈরি করে)।

কোডের সেই স্তরে কেবল স্টিমেন্টের অনুমতি রয়েছে .. তাই

j++; is a valid statement because it produces side effects

কিন্তু ব্রেকযুক্ত ব্যবহার করে আপনি এটিকে প্রকাশ হিসাবে পরিণত করছেন

myTempExpression = (j++)

এবং এই

myTempExpression;

বৈধ নয় কারণ সংকলকটি নিশ্চিত করে না যে পার্শ্ব প্রতিক্রিয়া হিসাবে অভিব্যক্তিটি (থামানো সমস্যার দিকে ঝুঁকি না নিয়ে) ..


হ্যাঁ, এটাই আমি প্রথমে ভেবেছিলাম। কিন্তু এই করে একটি পার্শ্ব প্রতিক্রিয়া আছে। এটি jভেরিয়েবলের পোস্ট-ইনক্রিমেন্টটি সম্পাদন করে ?
ব্যবহারকারী 10607

1
j++;একটি বৈধ বিবৃতি, তবে আপনি যে বন্ধনীগুলি বলছেন তা ব্যবহার করে let me take this stement and turn it into an expression.. এবং কোডের সময়
বিন্যাসগুলি

এটি খুব খারাপ যে "গণনা এবং উপেক্ষা করুন" স্টেটমেন্টের কোনও রূপ নেই কারণ এমন কিছু অনুষ্ঠান রয়েছে যখন কোডটি দাবি করতে পারে যে কোনও মান ব্যতিক্রম ছাড়াই গণনা করা যায়, তবে প্রকৃত মানটিকে এইভাবে গণনা করা যায় না। একটি গণনা এবং উপেক্ষা স্টেটমেন্টটি প্রায়শই ভয়ঙ্করভাবে ব্যবহৃত হত না, তবে এই ক্ষেত্রে প্রোগ্রামারের উদ্দেশ্য স্পষ্ট করে দেবে।
supercat
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.