সি ++ ফাংশন পরামিতিগুলিতে মূল্যায়নের ক্রম


90

আমাদের যদি তিনটি ফাংশন থাকে (ফু, বার এবং বাজ) যা এর মতো রচিত ...

foo(bar(), baz())

সি ++ স্ট্যান্ডার্ডের এমন কোনও গ্যারান্টি আছে যে বাজের আগে বারটি মূল্যায়ন করবে?

উত্তর:


102

না, এরকম কোনও গ্যারান্টি নেই। এটি সি ++ স্ট্যান্ডার্ড অনুযায়ী অনির্ধারিত।

বজর্ন স্ট্রস্ট্রপও কিছু যুক্তি সহ এটি "দ্য সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ" তৃতীয় সংস্করণ বিভাগে স্পষ্টভাবে বলেছেন:

এক্সপ্রেশন মূল্যায়ন আদেশের উপর বিধিনিষেধের অভাবে আরও ভাল কোড তৈরি করা যেতে পারে

যদিও প্রযুক্তিগতভাবে এটি একই বিভাগের পূর্ববর্তী অংশকে বোঝায় যা বলে যে একটি অভিব্যক্তির অংশগুলির মূল্যায়নের ক্রমটিও অনির্ধারিত, অর্থাৎ

int x = f(2) + g(3);   // unspecified whether f() or g() is called first

আমি এই উত্তরটি 8 মিনিটের মধ্যে গ্রহণ করতে পারি ... আমার ধারণা আমি কিছুটা সময় ধরে ঘুরে বেড়াচ্ছি!
ক্লার্ক গায়েবেল

4
হ্যাঁ, তবে এক্সপ্রেশন মূল্যায়নের ক্রমটি স্ট্রিক্ট হলে আরও ভাল কোডটি রাইটেন (= ক্লিনার) হতে পারে যা সাধারণত কোড জেনারেশনের চেয়ে অনেক বেশি গুরুত্বপূর্ণ। এই উদাহরণটি দেখুন: stackoverflow.com/questions/43612592/… সুতরাং, স্ট্রস্ট্রপ।
বিল কোটসিয়াস

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

4
এটি "অপরিজ্ঞাত" পরিবর্তে "অনির্দিষ্ট আচরণ" হওয়া উচিত নয়?
গুডডিডস

4
@ ক্রিসডড "অপরিজ্ঞাত" বনাম "অনির্ধারিত" শব্দটি ব্যবহার করার কারণে একটি গ্রহণযোগ্য উত্তরকে অবনমিত করে আমার কাছে দূষিত পেডেন্ট্রি বলে মনে হচ্ছে ... আমি এটি "অপরিজ্ঞাত" এবং "অনির্ধারিত" বলে মনে করি না প্রতিশব্দ? যাই হোক না কেন, উত্তরের একটি সম্পাদনার প্রস্তাব দেওয়া এটিকে নিয়ে আলোচনা করার আরও কার্যকর উপায় ছিল
এলি বেন্ডারস্কি

21

[5.2.2] ফাংশন কল থেকে,

যুক্তিগুলির মূল্যায়নের ক্রমটি অনির্ধারিত। ফাংশন প্রবেশের আগে যুক্তি প্রকাশের মূল্যায়নের সমস্ত পার্শ্ব প্রতিক্রিয়া কার্যকর হয়।

অতএব, কোনও গ্যারান্টি নেই যা bar()আগে চলবে baz(), কেবল এটিই bar()এবং এর baz()আগে ডাকা হবে foo

[5] থেকে প্রকাশিত অভিব্যক্তিগুলি থেকে নোট করুন:

যেখানে উল্লেখ করা হয়েছে [উদাহরণস্বরূপ এর জন্য বিশেষ বিধি &&এবং ||], পৃথক অপারেটরগুলির অপারেশনগুলির মূল্যায়নের ক্রম এবং স্বতন্ত্র এক্সপ্রেশনগুলির সুব এক্সপ্রেসন এবং পার্শ্ব প্রতিক্রিয়াগুলির ক্রমটি অনির্দিষ্ট the

তাই এমনকি যদি আপনি কিনা জিজ্ঞাসা করা হয় bar()আগে চালানো হবে baz()মধ্যে foo(bar() + baz()), অর্ডার এখনও অনির্দিষ্ট হয়।


4
লজিকাল অ্যান্ড অপারেটরের একটি "বিশেষ নোট" উদাহরণ: "বিপরীতে &, &&বাম থেকে ডানদিকের মূল্যায়নের গ্যারান্টি রয়েছে: দ্বিতীয় অপারেন্ডটি প্রথম অপারেন্ড হলে মূল্যায়ন হয় না false।"
ড্যানিয়েল ট্রেবিয়েন

20

বার () এবং বাজ () এর জন্য কোনও নির্দিষ্ট আদেশ নেই - স্ট্যান্ডার্ড যা বলেছে কেবল তা হ'ল foo () বলার আগে উভয়কেই মূল্যায়ন করা হবে। সি ++ স্ট্যান্ডার্ড থেকে বিভাগ 5.2.2 / 8:

যুক্তিগুলির মূল্যায়নের ক্রমটি অনির্ধারিত।


4
Foo () এর পূর্বে এগুলি মূল্যায়ন করা হয়েছে এটি কিছুটা আশ্বাস দেয়, কমপক্ষে।
বিল কোটসিয়াস

4
@ বিলকোটিসিয়াস স্ট্যান্ডার্ডটি আরও বলেছে যে ফাংশন কলগুলি ওভারল্যাপ করতে পারে না (অর্থাত্ একটি বাস্তবায়ন লাইন 1 এর লাইন 1 চালাতে পারে না bar, তারপরে লাইন 1 baz, তারপরে লাইন 2 barইত্যাদি), যা খুব সুন্দর। :-)
মেলপোমেন

12

সি ++ 17 অপারেটরদের জন্য মূল্যায়ন ক্রম নির্দিষ্ট করে যা সি ++ 17 পর্যন্ত অনির্দিষ্ট ছিল। প্রশ্নটি দেখুন সি ++ 17 দ্বারা প্রবর্তিত মূল্যায়ন আদেশের গ্যারান্টিগুলি কী কী? তবে আপনার অভিব্যক্তি নোট করুন

foo(bar(), baz())

এখনও নির্ধারিত মূল্যায়ন আদেশ আছে।


3

সি ++ 11 এ, প্রাসঙ্গিক পাঠ্য 8.3.6 ডিফল্ট আর্গুমেন্ট / 9 এ পাওয়া যাবে (জোর দিয়ে খনি)

ডিফল্ট আর্গুমেন্টগুলি প্রতিটি বার ফাংশনটি বলা হওয়ার পরে মূল্যায়ন করা হয়। ফাংশন আর্গুমেন্টগুলির মূল্যায়নের ক্রমটি অনির্দিষ্ট । ফলস্বরূপ, কোনও ক্রিয়াকলাপের প্যারামিটারগুলি মূল্যায়ন না হলেও ডিফল্ট যুক্তিতে ব্যবহার করা হবে না।

একই ভার্চিয়াটি সি ++ 14 স্ট্যান্ডার্ডও ব্যবহার করে এবং একই বিভাগে এটি পাওয়া যায় ।


0

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

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

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

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