সি ++ 17 দ্বারা প্রবর্তিত মূল্যায়ন আদেশের গ্যারান্টিগুলি কী কী?


95

টিপিক্যাল সি ++ কোডে সি ++ 17 মূল্যায়ন আদেশ গ্যারান্টিতে (P0145) ভোটের কী কী প্রভাব রয়েছে ?

নিম্নলিখিতগুলির মতো জিনিসগুলি সম্পর্কে এটি কী পরিবর্তন করে?

i = 1;
f(i++, i)

এবং

std::cout << f() << f() << f();

বা

f(g(), h(), j());

সি ++ তে অ্যাসাইনমেন্ট স্টেটমেন্টের মূল্যায়নের আদেশের সাথে সম্পর্কিত এবং "সি সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ" চতুর্থ সংস্করণ বিভাগ 36.3.6 থেকে এই কোডটির কি সুসংজ্ঞায়িত আচরণ রয়েছে? যা উভয়ই কাগজ দ্বারা আচ্ছাদিত করা হয়। প্রথমটি নীচে আপনার উত্তরে একটি দুর্দান্ত অতিরিক্ত উদাহরণ তৈরি করতে পারে।
শফিক ইয়াঘমুর

উত্তর:


83

কিছু সাধারণ ক্ষেত্রে যেখানে মূল্যায়ন আদেশ এখনও পর্যন্ত অনির্ধারিত ছিল , নির্দিষ্ট এবং এর সাথে বৈধ C++17। কিছু অপরিজ্ঞাত আচরণ এখন পরিবর্তে অনির্ধারিত।

i = 1;
f(i++, i)

অপরিবর্তিত ছিল, কিন্তু এটি এখন অনির্ধারিত। বিশেষত, যা নির্দিষ্ট করা হয়নি তা হ'ল প্রতিটি আদেশটি fঅন্যটির সাথে তুলনামূলকভাবে মূল্যায়ন করা হয়। i++আগে মূল্যায়ন করা যেতে পারে i, বা তদ্বিপরীত। প্রকৃতপক্ষে, এটি একই সংকলকের অধীনে থাকা সত্ত্বেও এটি একটি দ্বিতীয় ক্রমে দ্বিতীয় কলকে মূল্যায়ন করতে পারে।

তবে, প্রতিটি যুক্তি মূল্যায়ন করা হয় প্রয়োজনীয় অন্য কোন যুক্তি সঞ্চালনের আগে সব পার্শ্ব প্রতিক্রিয়া সাথে সম্পূর্ণরূপে চালানো,। সুতরাং আপনি পেতে পারেন f(1, 1)(দ্বিতীয় যুক্তি প্রথমে মূল্যায়ন করা) বা f(1, 2)(প্রথম যুক্তিটি প্রথমে মূল্যায়ন করা)। তবে আপনি কখনও পাবেন না f(2, 2)বা সেই প্রকৃতির আর কিছু পাবেন না ।

std::cout << f() << f() << f();

অনির্ধারিত ছিল, তবে এটি অপারেটর প্রাধান্যের সাথে সামঞ্জস্যপূর্ণ হবে যাতে এর প্রথম মূল্যায়নটি fপ্রথম প্রবাহে আসে (নীচে উদাহরণগুলি)।

f(g(), h(), j());

এখনও জি, এইচ এবং জ এর অনির্দিষ্ট মূল্যায়ন আদেশ রয়েছে। নোট যে জন্য getf()(g(),h(),j()), বিধি মতে getf()আগে মূল্যায়ন করা হবে g, h, j

প্রস্তাবিত পাঠ্য থেকে নীচের উদাহরণটিও নোট করুন:

 std::string s = "but I have heard it works even if you don't believe in it"
 s.replace(0, 4, "").replace(s.find("even"), 4, "only")
  .replace(s.find(" don't"), 6, "");

উদাহরণটি সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ , চতুর্থ সংস্করণ, স্ট্রাস্ট্রাপ থেকে এসেছে এবং অনির্দিষ্ট আচরণ হিসাবে ব্যবহৃত হয়েছিল, তবে সি ++ 17 দিয়ে এটি প্রত্যাশার মতো কাজ করবে। পুনরায় শুরুযোগ্য ফাংশনগুলির সাথে একই সমস্যা ছিল ( .then( . . . ))।

অন্য উদাহরণ হিসাবে, নিম্নলিখিত বিবেচনা করুন:

#include <iostream>
#include <string>
#include <vector>
#include <cassert>

struct Speaker{
    int i =0;
    Speaker(std::vector<std::string> words) :words(words) {}
    std::vector<std::string> words;
    std::string operator()(){
        assert(words.size()>0);
        if(i==words.size()) i=0;
        // Pre-C++17 version:
        auto word = words[i] + (i+1==words.size()?"\n":",");
        ++i;
        return word;
        // Still not possible with C++17:
        // return words[i++] + (i==words.size()?"\n":",");

    }
};

int main() {
    auto spk = Speaker{{"All", "Work", "and", "no", "play"}};
    std::cout << spk() << spk() << spk() << spk() << spk() ;
}

সি ++ এর সাথে এবং এর আগে আমরা ফলাফল পেতে পারি (এবং করব) এর আগেও

play
no,and,Work,All,

পরিবর্তে

All,work,and,no,play

নোট করুন যে উপরেরটি কার্যকর হিসাবে একই

(((((std::cout << spk()) << spk()) << spk()) << spk()) << spk()) ;

তবে তবুও, সি ++ 17 এর আগে এমন কোনও গ্যারান্টি ছিল না যে প্রথম কলগুলি প্রথম প্রবাহে আসবে।

তথ্যসূত্র: গৃহীত প্রস্তাবনা থেকে :

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

অ্যাসাইনমেন্ট এক্সপ্রেশনগুলি ডান থেকে বামে মূল্যায়ন করা হয়। এর মধ্যে যৌগিক কার্যভার অন্তর্ভুক্ত রয়েছে।

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

  1. আব
  2. a-> খ
  3. a -> * খ
  4. ক (বি 1, বি 2, বি 3)
  5. খ @ = ক
  6. একটি [খ]
  7. ক << খ
  8. a >> খ

তদুপরি, আমরা নিম্নলিখিত অতিরিক্ত নিয়মটি পরামর্শ দিই: একটি ওভারলোডেড অপারেটর জড়িত একটি এক্সপ্রেশন মূল্যায়নের ক্রমটি সংশ্লিষ্ট বিল্ট-ইন অপারেটরের সাথে সম্পর্কিত আদেশ দ্বারা নির্ধারিত হয়, ফাংশন কলের নিয়ম নয়।

সম্পাদনা দ্রষ্টব্য: আমার মূল উত্তরটি ভুল ব্যাখ্যা করা হয়েছে a(b1, b2, b3)। ক্রম b1, b2, b3এখনও অনির্দিষ্ট হয়। (আপনাকে ধন্যবাদ সমস্ত মন্তব্যকারী @ কেবিওসনোনাউল্ট।)

যাইহোক, (@Yakk পয়েন্ট আউট হিসাবে) এবং এই গুরুত্বপূর্ণ: এমনকি যখন b1, b2, b3, অ-তুচ্ছ এক্সপ্রেশন হয় তাদের প্রতিটি সম্পূর্ণরূপে মূল্যায়ন করা হয় এবং নিজ নিজ ফাংশন প্যারামিটার বাঁধা অন্যান্য বেশী মূল্যায়ন করা শুরু হয় আগে। স্ট্যান্ডার্ড এটিকে এভাবে বলে:

§5.2.2 - ফাংশন কল 5.2.2.4:

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

যাইহোক, এই নতুন বাক্যগুলির মধ্যে একটি গিটহাব খসড়া থেকে অনুপস্থিত :

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

উদাহরণস্বরূপ হয় না। এটি কয়েক দশকের পুরানো সমস্যাগুলি ( যেমন হার্ব সটার ব্যাখ্যা করেছেন ) ব্যতিক্রমী সুরক্ষার সাথে সমাধান করে যেখানে জিনিস পছন্দ করে

f(std::unique_ptr<A> a, std::unique_ptr<B> b);

f(get_raw_a(), get_raw_a());

get_raw_a()অন্য কোনও কাঁচা পয়েন্টারটির স্মার্ট পয়েন্টার প্যারামিটারের সাথে যুক্ত হওয়ার আগে যদি কলগুলির মধ্যে একটি ছুটে যায় তবে তা ফাঁস হবে।

টিসি দ্বারা নির্দেশিত হিসাবে, উদাহরণটি ত্রুটিযুক্ত যেহেতু কাঁচা পয়েন্টার থেকে অনন্য_পিট্রিক নির্মাণ স্পষ্ট, এটি সংকলন থেকে রোধ করে।

এই ধ্রুপদী প্রশ্নটিও নোট করুন (ট্যাগ করা সি , সি ++ নয় ):

int x=0;
x++ + ++x;

এখনও অপরিজ্ঞাত।


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

4
আমি কাগজটি থেকে এই ধারণাটি পেয়ে যাচ্ছি যে "নিম্নলিখিত ক্রিয়াকলাপগুলি ক্রমে মূল্যায়ন করা হয় a, তারপরে b, তারপরে c, তারপরে d" এবং তারপরে দেখানো হচ্ছে a(b1, b2, b3)যে সমস্ত bক্রিয়াকলাপটি কোনও ক্রমে প্রয়োজনীয়ভাবে মূল্যায়ন করা হয় না (অন্যথায়, এটি হবে a(b, c, d))
KABoissonneault

4
@ কেবিসোসোনল্ট, আপনি সঠিক এবং আমি সেই অনুযায়ী উত্তর আপডেট করেছি। এছাড়াও, সব: কোট হয় ফর্ম সংস্করণ 3, যা যতদূর আমি বুঝতে সংস্করণে ভোট হয়।
জোহান লন্ডবার্গ

4
@ জোহানলুন্ডবার্গ পেপার থেকে অন্য একটি জিনিস রয়েছে যা আমি বিশ্বাস করি যে এটি গুরুত্বপূর্ণ। a(b1()(), b2()())অর্ডার করতে পারেন b1()()এবং b2()()কোন অনুক্রমে, কিন্তু এটা করতে পারবে না কি b1()তারপর b2()()তারপর b1()(): এটা তাদের মৃত্যুদণ্ড কার্যকর করা ইন্টারলিভ আর হতে পারে। সংক্ষেপে, "8. ফাংশন কলের জন্য বিকল্প মূল্য নির্দেশ" অনুমোদিত পরিবর্তনের অংশ ছিল।
ইয়াক্ক - অ্যাডাম নেভ্রামামন্ট

4
f(i++, i)অপরিবর্তিত ছিল। এটি এখন অনির্ধারিত। স্ট্রস্ট্রপের স্ট্রিং উদাহরণটি সম্ভবত অনির্ধারিত ছিল, অপরিজ্ঞাত নয়। const f (get_raw_a (), get_raw_a ()); comp সংকলন করবে না যেহেতু প্রাসঙ্গিক unique_ptrনির্মাণকারী সুস্পষ্ট is শেষ x++ + ++xঅবধি, সময় নির্ধারণ করা হয়।
টিসি

44

সি ++ 17 এ ইন্টারলেভিং নিষিদ্ধ

সি ++ এ, নিম্নলিখিতগুলি অনিরাপদ ছিল:

void foo(std::unique_ptr<A>, std::unique_ptr<B>);

foo(std::unique_ptr<A>(new A), std::unique_ptr<B>(new B));

ফাংশন কল চলাকালীন এখানে চারটি অপারেশন ঘটে

  1. new A
  2. unique_ptr<A> নির্মাতা
  3. new B
  4. unique_ptr<B> নির্মাতা

এর ক্রমটি সম্পূর্ণরূপে অনির্দিষ্ট ছিল এবং সুতরাং একেবারে বৈধ অর্ডারিং (1), (3), (2), (4)। যদি এই ক্রমটি নির্বাচিত হয় এবং (3) ছুঁড়ে ফেলা হয়, তবে (1) ফাঁস হওয়া মেমরিটি - আমরা এখনও চালানো হয়নি (2), যা ফাঁস ঠেকিয়ে দিত।


সি ++ 17 এ, নতুন বিধিগুলি ইন্টারলেভিং নিষিদ্ধ করেছে। [অন্তঃসত্ত্বা] থেকে:

প্রতিটি ফাংশন প্রার্থনার জন্য এফ, প্রতিটি মূল্যায়নের জন্য যা এফ এর মধ্যে ঘটে থাকে এবং প্রতিটি মূল্যায়ন বি যা এফ এর মধ্যে ঘটে না তবে একই থ্রেডে এবং একই সংকেত হ্যান্ডলারের অংশ হিসাবে (যদি থাকে) হয়, হয় হয় বি এর আগে ধারাবাহিকভাবে বা বি এ এর ​​আগে সিকোয়েন্সড হয় B

সেই বাক্যটির একটি পাদটীকা রয়েছে যা এতে লেখা আছে:

অন্য কথায়, ফাংশন মৃত্যুদণ্ড একে অপরের সাথে ইন্টারলিভ করে না।

এটি আমাদের দুটি বৈধ অর্ডার দিয়ে ফেলেছে: (1), (2), (3), (4) বা (3), (4), (1), (2) কোন অর্ডার নেওয়া হয়েছে তা অনির্ধারিত, তবে উভয়ই নিরাপদ। (1) (3) উভয় (2) এবং (4) এর আগে ঘটে এমন সমস্ত ক্রম এখন নিষিদ্ধ।


4
কিছুটা হলেও বাদ দেওয়া, তবে এটি :: মেক_শেয়ার্ড এবং পরে স্টাড :: মেক_শ্রেড করা (অন্য কারণে কম বরাদ্দ থাকায় + আরও ভাল লোকালয়) বাড়ানোর অন্যতম কারণ ছিল। ব্যতিক্রম-সুরক্ষা / রিসোর্স-লিক প্রেরণার মতো শব্দগুলি আর প্রযোজ্য নয়। দেখুন কোড উদাহরণ 3, boost.org/doc/libs/1_67_0/libs/smart_ptr/doc/html/... সম্পাদনা এবং stackoverflow.com/a/48844115 , herbsutter.com/2013/05/29/gotw-89-solution- স্মার্ট পয়েন্টার
ম্যাক্স ব্যারাক্লফ

4
আমি ভাবছি কীভাবে এই পরিবর্তনটি অপ্টিমাইজেশনকে প্রভাবিত করে। সংকলকটি এখন আর্গুমেন্ট গণনা সম্পর্কিত সিপিইউ নির্দেশাবলীকে কীভাবে একত্রিত করতে ও ইন্টারলিভ করার জন্য বিকল্পগুলির সংখ্যা গুরুতরভাবে হ্রাস করেছে, সুতরাং এটি দরিদ্র সিপিইউ ব্যবহারের দিকে পরিচালিত করতে পারে?
ভায়োলেট জিরাফ 22'19

2

আমি এক্সপ্রেশন মূল্যায়ন আদেশ সম্পর্কে কিছু নোট পেয়েছি:

  • দ্রুত প্রশ্ন: ফাংশন আর্গুমেন্টগুলি মূল্যায়নের জন্য সি ++ এর কেন একটি নির্দিষ্ট আদেশ নেই?

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

  • মূল্যায়নের আদেশ

    ২১) প্রথম বন্ধকের প্রথম প্রান্তে কমা-বিচ্ছিন্ন অভিব্যক্তির তালিকাতে প্রতিটি অভিব্যক্তি ফাংশন কলের জন্য এমনভাবে মূল্যায়ন করা হয় ( অনির্দিষ্টভাবে-ক্রমযুক্ত )

  • অস্পষ্ট প্রকাশ

    সি ++ ভাষা সেই ক্রমানুসারে গ্যারান্টি দেয় না যাতে কোনও ফাংশন কলের আর্গুমেন্ট মূল্যায়ন করা হয়।

ইন কথ্য সি জন্য এক্সপ্রেশন মূল্যায়ন অর্ডার P0145R3.Refining ++, আমি পেয়েছি:

পোস্টফিক্স-এক্সপ্রেশনটির মান গণনা এবং সম্পর্কিত পার্শ্ব-প্রতিক্রিয়াটি এক্সপ্রেশন-তালিকায় থাকা এক্সপ্রেশনগুলির আগে ক্রমযুক্ত হয়। ঘোষিত প্যারামিটারগুলির সূচনাটি অনির্দিষ্টকালের জন্য বিন্যাস ছাড়াই ক্রমযুক্ত

তবে আমি এটি স্ট্যান্ডার্ডে পাইনি, পরিবর্তে স্ট্যান্ডার্ডের মধ্যে আমি পেয়েছি:

6.8.1.8 অনুক্রমিক সঞ্চালনের [intro.execution] একটি অভিব্যক্তি এক্স যদি প্রত্যেক মান হিসাব এবং অভিব্যক্তি এক্স সঙ্গে যুক্ত প্রত্যেক পার্শ্ব প্রতিক্রিয়া যে মান হিসাব এবং অভিব্যক্তি ওয়াই সঙ্গে যুক্ত প্রত্যেক পার্শ্ব প্রতিক্রিয়া সামনে সিকোয়েন্স করা হয় একটি অভিব্যক্তি ওয়াই আগে সিকোয়েন্স করা হয়েছে ।

8.৮.১.৯ সিক্যুয়ালিয়াল এক্সিকিউশন [অন্তঃকরণ। এক্সিকিউশন] একটি পূর্ণ-এক্সপ্রেশনের সাথে যুক্ত প্রতিটি মান গণনা এবং পার্শ্ব প্রতিক্রিয়াটি পরবর্তী পূর্ণ-এক্সপ্রেশনটির সাথে সম্পর্কিত প্রতিটি মান গণনা এবং পার্শ্ব প্রতিক্রিয়াটি মূল্যায়ন করার আগে ক্রমযুক্ত হয়।

.6..6.১৯.১ কমা অপারেটর [expr.comma] কমা দ্বারা পৃথককৃত এক জোড়া অভিব্যক্তি বাম থেকে ডানে মূল্যায়ন করা হয়; ...

সুতরাং, আমি 14 এবং 17 মানের জন্য তিনটি সংকলক মধ্যে আচরণ অনুযায়ী তুলনা করেছি। এক্সপ্লোর করা কোডটি হ'ল:

#include <iostream>

struct A
{
    A& addInt(int i)
    {
        std::cout << "add int: " << i << "\n";
        return *this;
    }

    A& addFloat(float i)
    {
        std::cout << "add float: " << i << "\n";
        return *this;
    }
};

int computeInt()
{
    std::cout << "compute int\n";
    return 0;
}

float computeFloat()
{
    std::cout << "compute float\n";
    return 1.0f;
}

void compute(float, int)
{
    std::cout << "compute\n";
}

int main()
{
    A a;
    a.addFloat(computeFloat()).addInt(computeInt());
    std::cout << "Function call:\n";
    compute(computeFloat(), computeInt());
}

ফলাফল (আরও ধারাবাহিকভাবে ঝাঁকুনি):

<style type="text/css">
  .tg {
    border-collapse: collapse;
    border-spacing: 0;
    border-color: #aaa;
  }
  
  .tg td {
    font-family: Arial, sans-serif;
    font-size: 14px;
    padding: 10px 5px;
    border-style: solid;
    border-width: 1px;
    overflow: hidden;
    word-break: normal;
    border-color: #aaa;
    color: #333;
    background-color: #fff;
  }
  
  .tg th {
    font-family: Arial, sans-serif;
    font-size: 14px;
    font-weight: normal;
    padding: 10px 5px;
    border-style: solid;
    border-width: 1px;
    overflow: hidden;
    word-break: normal;
    border-color: #aaa;
    color: #fff;
    background-color: #f38630;
  }
  
  .tg .tg-0pky {
    border-color: inherit;
    text-align: left;
    vertical-align: top
  }
  
  .tg .tg-fymr {
    font-weight: bold;
    border-color: inherit;
    text-align: left;
    vertical-align: top
  }
</style>
<table class="tg">
  <tr>
    <th class="tg-0pky"></th>
    <th class="tg-fymr">C++14</th>
    <th class="tg-fymr">C++17</th>
  </tr>
  <tr>
    <td class="tg-fymr"><br>gcc 9.0.1<br></td>
    <td class="tg-0pky">compute float<br>add float: 1<br>compute int<br>add int: 0<br>Function call:<br>compute int<br>compute float<br>compute</td>
    <td class="tg-0pky">compute float<br>add float: 1<br>compute int<br>add int: 0<br>Function call:<br>compute int<br>compute float<br>compute</td>
  </tr>
  <tr>
    <td class="tg-fymr">clang 9</td>
    <td class="tg-0pky">compute float<br>add float: 1<br>compute int<br>add int: 0<br>Function call:<br>compute float<br>compute int<br>compute</td>
    <td class="tg-0pky">compute float<br>add float: 1<br>compute int<br>add int: 0<br>Function call:<br>compute float<br>compute int<br>compute</td>
  </tr>
  <tr>
    <td class="tg-fymr">msvs 2017</td>
    <td class="tg-0pky">compute int<br>compute float<br>add float: 1<br>add int: 0<br>Function call:<br>compute int<br>compute float<br>compute</td>
    <td class="tg-0pky">compute float<br>add float: 1<br>compute int<br>add int: 0<br>Function call:<br>compute int<br>compute float<br>compute</td>
  </tr>
</table>

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