নতুন স্ট্যান্ডার্ড সংস্করণ সহ সি ++ তে কি কখনও নীরব আচরণ পরিবর্তন হয়েছে?


104

(আমি একটি তালিকা নয়, বিষয়টি প্রমাণ করার জন্য দু'একটি উদাহরণ খুঁজছি))

এমন কি কখনও ঘটেছে যে সি ++ স্ট্যান্ডার্ডের পরিবর্তন (যেমন 98 থেকে 11, 11 থেকে 14 ইত্যাদি) বিদ্যমান, সুগঠিত, সংজ্ঞায়িত-আচরণ ব্যবহারকারী কোডের আচরণ - নীরবে? অর্থাত্ নতুন স্ট্যান্ডার্ড সংস্করণটি সংকলন করার সময় কোনও সতর্কতা বা ত্রুটিযুক্ত না?

মন্তব্য:

  • আমি মানক-বাধ্যতামূলক আচরণ সম্পর্কে জিজ্ঞাসা করছি, প্রয়োগকারী / সংকলক লেখকের পছন্দ সম্পর্কে নয়।
  • কোডটি যত কম ভাগ করা হয়েছে তত ভাল (এই প্রশ্নের উত্তর হিসাবে)।
  • আমি সংস্করণ সনাক্তকরণ সহ কোডটি বোঝাতে চাইছি না #if __cplusplus >= 201103L
  • মেমরি মডেল জড়িত উত্তর ঠিক আছে।

মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
স্যামুয়েল লিউ

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

আমার মনে, বৃহত্তম নীরব ব্রেকিং পরিবর্তনটির নতুন সংজ্ঞা auto। সি ++ 11 এর আগে auto x = ...;একটি ঘোষণা করে int। পরে, এটি যা আছে তা ঘোষণা করে ...
রেমন্ড চেন

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

সত্য, এ কারণেই তারা এটিকে বেছে নিয়েছে। তবে এটি শব্দার্থবিজ্ঞানের একটি বিশাল পরিবর্তন ছিল।
রেমন্ড চেন

উত্তর:


113

এর রিটার্ন টাইপ string::dataথেকে পরিবর্তন const char*করতে char*17. সি ++ সেই অবশ্যই একটি পার্থক্য করতে পারে

void func(char* data)
{
    cout << data << " is not const\n";
}

void func(const char* data)
{
    cout << data << " is const\n";
}

int main()
{
    string s = "xyz";
    func(s.data());
}

কিছুটা স্বীকৃত তবে এই আইনি প্রোগ্রামটি এর আউটপুট সি ++ 14 থেকে সি ++ 17 এ পরিবর্তন করবে।


7
ওহ, আমি এমনকি std::stringসি ++ 17 এর পরিবর্তনগুলি বুঝতে পারি নি । যদি কিছু হয় তবে আমি ভেবেছিলাম সি ++ 11 পরিবর্তনগুলি কোনওভাবে নীরব আচরণের পরিবর্তনের কারণ হতে পারে। +1
einpoklum

9
এতে অবদান রয়েছে বা নেই, এটি বেশ ভালভাবে গঠিত কোডটিতে একটি পরিবর্তন প্রদর্শন করে।
ডেভিড সি র্যাঙ্কিন

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

81

উত্তর এই প্রশ্নের দেখায় কিভাবে একটি ভেক্টর একটি একক ব্যবহার আরম্ভের size_typeমান সি ++ 03 এবং সি ++ 11 মধ্যে পার্থক্য আচরণ হতে পারে।

std::vector<Something> s(10);

সি ++ 03 ডিফল্ট-উপাদান উপাদানটির একটি অস্থায়ী অবজেক্ট তৈরি করে Somethingএবং সেই অস্থায়ী থেকে ভেক্টরের প্রতিটি উপাদানকে অনুলিপি তৈরি করে।

সি ++ 11 ডিফল্ট ভেক্টরে প্রতিটি উপাদান তৈরি করে।

অনেকগুলি (সর্বাধিক?) ক্ষেত্রে এগুলি সমতুল্য চূড়ান্ত অবস্থার ফলস্বরূপ, তবে তাদের কোনও কারণ নেই। এটি Somethingডিফল্ট / অনুলিপি নির্মাণকারীদের প্রয়োগের উপর নির্ভর করে ।

দেখুন এই কল্পিত উদাহরণ :

class Something {
private:
    static int counter;

public:
    Something() : v(counter++) {
        std::cout << "default " << v << '\n';
    }

    Something(Something const & other) : v(counter++) {
        std::cout << "copy " << other.v << " to " << v << '\n';
    }

    ~Something() {
        std::cout << "dtor " << v << '\n';
    }

private:
    int v;
};

int Something::counter = 0;

সি ++ 03 এর Somethingসাথে একটি ডিফল্ট-নির্মাণ করবে v == 0তারপরে তার থেকে আরও দশটি অনুলিপি করুন। শেষে, ভেক্টরটিতে দশটি অবজেক্ট রয়েছে যার vমান 1 থেকে 10, সমেত।

সি ++ 11 প্রতিটি উপাদানকে ডিফল্ট-নির্মাণ করবে। কোনও কপি তৈরি করা হয় না। শেষে, ভেক্টরটিতে দশটি অবজেক্ট রয়েছে যার vমান 0 থেকে 9, সমেত।


যদিও আইনপোকলুম আমি একটি স্বীকৃত উদাহরণ যুক্ত করেছি। :)
সিডিওউই

4
আমি মনে করি না এটি সংবিধানযুক্ত। বিভিন্ন কনস্ট্রাক্টর প্রায়শই বিভিন্নভাবে কব্জিযুক্ত জিনিসগুলি যেমন বলুন, মেমরি বরাদ্দ করে। আপনি কেবলমাত্র একটি পার্শ্ব প্রতিক্রিয়াটিকে অন্য (আই / ও) দিয়ে প্রতিস্থাপন করেছেন।
einpoklum

17
পছন্দ করেছেন আমি সম্প্রতি একটি ইউইউডি ক্লাসে কাজ করছিলাম। ডিফল্ট কনস্ট্রাক্টর একটি এলোমেলোভাবে ইউআইডি উত্পন্ন করে। এই সম্ভাবনা সম্পর্কে আমার কোনও ধারণা ছিল না, আমি কেবল সি ++ 11 আচরণ অনুমান করেছি।
জন

4
এক বহুল ব্যবহৃত ক্লাসের বাস্তব জগতে উদাহরণ যেখানে এই ব্যাপার হবে OpenCV হয় cv::mat। ডিফল্ট কনস্ট্রাক্টর নতুন মেমরি বরাদ্দ করে, যখন অনুলিপি নির্মাণকারী বিদ্যমান মেমরিতে নতুন ভিউ তৈরি করে।
জেপা

আমি এটিকে একটি দ্বন্দ্বযুক্ত উদাহরণ বলব না, এটি আচরণের পার্থক্যটি পরিষ্কারভাবে দেখায়।
ডেভিড ওয়াটারওয়ার্থ

51

স্ট্যান্ডার্ডটিতে অ্যাঙ্কেক্স সি [ডিফ] মধ্যে ব্রেকিং পরিবর্তনের একটি তালিকা রয়েছে । এই পরিবর্তনগুলির মধ্যে অনেকগুলি নীরব আচরণ পরিবর্তনের দিকে পরিচালিত করতে পারে।

একটি উদাহরণ:

int f(const char*); // #1
int f(bool);        // #2

int x = f(u8"foo"); // until C++20: calls #1; since C++20: calls #2

7
@ আইনপোকলুম ভাল, তাদের মধ্যে কমপক্ষে এক ডজন লোককে বিদ্যমান কোডের "অর্থ পরিবর্তন" করতে বা তাদের "আলাদাভাবে কার্যকর করতে" বলা হয়।
সিপ্লেয়ারার

4
আপনি কীভাবে এই বিশেষ পরিবর্তনের জন্য যুক্তি সংক্ষিপ্তসার করবেন?
নায়ুকি

4
@ নयुুকি নিশ্চিতভাবেই নিশ্চিত যে boolসংস্করণটি ব্যবহার করা সেকেন্ডে কোনও পরিবর্তিত নিয়ম নয়, কেবল অন্য রূপান্তর নিয়মের একটি পার্শ্ব প্রতিক্রিয়া। আসল উদ্দেশ্য হ'ল অক্ষর এনকোডিংগুলির মধ্যে কিছু বিভ্রান্তি বন্ধ করা, আসল পরিবর্তন যা u8আক্ষরিকরাই দিত const char*কিন্তু এখন দেয় const char8_t*

25

প্রতিবার তারা স্ট্যান্ডার্ড লাইব্রেরিতে নতুন পদ্ধতি যুক্ত করে (এবং প্রায়শই কাজ করে) এটি ঘটে।

ধরুন আপনার কাছে একটি স্ট্যান্ডার্ড লাইব্রেরি টাইপ রয়েছে:

struct example {
  void do_stuff() const;
};

বেশ সহজ. কিছু মানক পুনর্বিবেচনায় একটি নতুন পদ্ধতি বা ওভারলোড বা কোনও কিছুর পাশে যুক্ত করা হয়:

struct example {
  void do_stuff() const;
  void method(); // a new method
};

এটি চুপচাপ বিদ্যমান সি ++ প্রোগ্রামগুলির আচরণ পরিবর্তন করতে পারে।

এটি কারণ কারণ বর্তমানে সি ++ এর সীমাবদ্ধ প্রতিফলন ক্ষমতাগুলি এ জাতীয় পদ্ধতি বিদ্যমান কিনা তা সনাক্ত করতে এবং এর ভিত্তিতে বিভিন্ন কোড চালানোর জন্য যথেষ্ট ।

template<class T, class=void>
struct detect_new_method : std::false_type {};

template<class T>
struct detect_new_method< T, std::void_t< decltype( &T::method ) > > : std::true_type {};

এটি নতুন সনাক্ত করার জন্য একটি অপেক্ষাকৃত সহজ উপায় method, বিভিন্ন উপায়ে রয়েছে।

void task( std::false_type ) {
  std::cout << "old code";
};
void task( std::true_type ) {
  std::cout << "new code";
};

int main() {
  task( detect_new_method<example>{} );
}

আপনি ক্লাস থেকে পদ্ধতিগুলি সরিয়ে ফেললে একই ঘটনা ঘটতে পারে।

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

মানটি কোনও ধারকটিতে যায় এবং একটি .data()পদ্ধতি যুক্ত করে, এবং হঠাৎ টাইপটি পরিবর্তন করে যা সিরিয়ালের জন্য ব্যবহৃত হয়।

সমস্ত সি ++ স্ট্যান্ডার্ড যা করতে পারে তা যদি এটি হিমায়িত করতে না চায় তবে হ'ল এমন ধরণের কোড তৈরি করা যা নিঃশব্দে বিরতি দেয় বা কোনওরকমভাবে অযৌক্তিক হয়।


4
SFINAE কে বাদ দেওয়ার জন্য আমার প্রশ্নের যোগ্যতা অর্জন করা উচিত ছিল কারণ এটি আমি বোঝাতে চাইছি না ... তবে হ্যাঁ, এটি সত্য, সুতরাং +1।
einpoklum

"এই ধরণের ঘটনা পরোক্ষভাবে ঘটছে" এর ফলে একটি উত্সাহ হয়েছিল বরং ডাউনভোট হয়েছিল কারণ এটি বাস্তব জাল।
ইয়ান রিংরোজ

4
এটি সত্যিই একটি ভাল উদাহরণ। যদিও ওপি এর অর্থ এটি বাদ দেয়, এটি সম্ভবত বিদ্যমান কোডে নীরব আচরণের পরিবর্তনগুলির অন্যতম সম্ভাব্য বিষয় things +1
সিডিউইউই

4
@ টেডলিঙ্গমো আপনি যদি ডিটেক্টরটি ঠিক করতে না পারেন তবে সনাক্ত করা জিনিসটি পরিবর্তন করুন। টেক্সাসের শার্পশুটিং!
ইয়াক্ক - অ্যাডাম নেভ্রামামন্ট

15

ওহ ছেলে ... লিংক cpplearner প্রদান হয় ভীতিকর

অন্যদের মধ্যে, সি ++ 20 সি ++ স্ট্রাক্টের সি-স্টাইলের স্ট্রাক্ট ঘোষণা নিষিদ্ধ করে।

typedef struct
{
  void member_foo(); // Ill-formed since C++20
} m_struct;

যদি আপনাকে সেইরকম স্ট্রাক্ট লেখার বিষয়ে শেখানো হয় (এবং "ক্লাস সহ সি পড়ানো লোকেরা" ঠিক সেভাবে শেখায়) তবে আপনি ভুল হয়ে গেছেন



19
@ পিটার-রেইনস্টেটমোনিকা ভাল, আমি সবসময় typedefআমার স্ট্রাক্টস এবং আমি অবশ্যই এটিতে আমার খড়ি নষ্ট করব না। এটি অবশ্যই স্বাদের বিষয়, এবং যখন আপনার মতামতটি অত্যন্ত প্রভাবশালী ব্যক্তিরা (টরভাল্ডস ...) ভাগ করে নিচ্ছেন, তখন আমার মতো অন্যান্য লোকেরাও উল্লেখ করবে যে, প্রকারের জন্য নামকরণের একটি কনভেনশন যা প্রয়োজন তা কেবল। structমূলশব্দ ( MyClass* object = myClass_create();)) মূল অক্ষরটি প্রকাশ করবে না এমন বোঝার সাথে কীওয়ার্ড সহ কোডটিকে ছড়িয়ে দেওয়া কিছুটা যোগ করে । আপনি যদি আপনার কোডটিতে চান তবে আমি এটি শ্রদ্ধা করি struct। তবে আমার তা চাই না।
কাস্টমস্টার

4
এটি বলেছিল যে, যখন সি ++ প্রোগ্রামিং করা হয় তখন structকেবল প্লেইন-পুরাতন-ডেটা ধরণের জন্য এবং classসদস্যের কার্যকারিতা সহ যে কোনও কিছুর জন্য এটি ব্যবহার করা ভাল একটি সম্মেলন । সেখানে কোন কিন্তু আপনি সি যে কনভেনশন ব্যবহার করতে পারবেন না classসি
cmaster - পুনর্বহাল মনিকা

4
@ পিটার-রেইনস্টেটমোনিকা হ্যাঁ, ভাল আপনি সিতে সিনথেটিকভাবে কোনও পদ্ধতি সংযুক্ত করতে পারবেন না, তবে এর অর্থ এই নয় যে একটি সি structআসলে পিওড। আমি সি কোডটি যেভাবে লিখি, বেশিরভাগ কাঠামো কেবলমাত্র একটি ফাইলে কোড দ্বারা এবং তাদের শ্রেণীর নাম বহন করে এমন ফাংশনগুলির দ্বারা স্পর্শ করা হয়। এটি সিনট্যাকটিক চিনি ছাড়া মূলত ওওপি। এটি আমাকে আসলে ক এর অভ্যন্তরে কী পরিবর্তন হয় structএবং এর সদস্যদের মধ্যে কোন আক্রমণকারী গ্যারান্টিযুক্ত তা নিয়ন্ত্রণ করতে দেয়। সুতরাং, আমার structsসদস্য ফাংশন, ব্যক্তিগত বাস্তবায়ন, আক্রমণকারী এবং তাদের ডেটা সদস্যদের থেকে বিমূর্তকরণের ঝোঁক রয়েছে। পিওডের মতো শোনাচ্ছে না, তাই না?
মাস্টার

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

15

এখানে একটি উদাহরণ যা C ++ 03 তে 3 প্রিন্ট করে তবে 0+ তে C ++ 11:

template<int I> struct X   { static int const c = 2; };
template<> struct X<0>     { typedef int c; };
template<class T> struct Y { static int const c = 3; };
static int const c = 4;
int main() { std::cout << (Y<X< 1>>::c >::c>::c) << '\n'; }

আচরণে এই পরিবর্তনটি বিশেষভাবে পরিচালনার কারণে হয়েছিল >>। সি ++ 11 এর আগে >>সর্বদা ডান শিফট অপারেটর ছিল। সি ++ 11 >>দিয়েও কোনও টেম্পলেট ঘোষণার অংশ হতে পারে।


ঠিক আছে, প্রযুক্তিগতভাবে এটি সত্য তবে এই উপায়টি ব্যবহারের কারণে এই কোডটি "অনানুষ্ঠানিকভাবে অস্পষ্ট" ছিল >>
einpoklum

11

ত্রিগ্রাফগুলি বাদ পড়েছে

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

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

আরও বাধা আছে char

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

সি ++ স্ট্যান্ডার্ডটি charসম্ভবত-স্বাক্ষরিত ইন্টিগ্রাল টাইপ হিসাবে নির্ধারিত হয়েছে যা কার্যকরভাবে অক্ষর সংকলনের প্রতিটি মানকে দক্ষতার সাথে উপস্থাপন করতে পারে। কোনও ভাষা আইনজীবীর উপস্থাপনের সাথে আপনি যুক্তি দিতে পারেন যে charকমপক্ষে 8 টি বিট থাকতে হবে।

যদি আপনার প্রয়োগটি এর জন্য স্বাক্ষরবিহীন মান ব্যবহার করে charতবে আপনি জানেন যে এটি 0 থেকে 255 অবধি হতে পারে এবং এটি প্রতিটি সম্ভাব্য বাইট মান সংরক্ষণের জন্য উপযুক্ত।

তবে যদি আপনার প্রয়োগটি একটি স্বাক্ষরিত মান ব্যবহার করে তবে এর বিকল্প রয়েছে।

বেশিরভাগ দু'টির পরিপূরক ব্যবহার করবে, charসর্বনিম্ন -128 থেকে 127 অবধি প্রদান করবে That's এটি 256 অনন্য মান।

তবে অন্য বিকল্পটি ছিল চিহ্ন + মাত্রা, যেখানে একটি বিটটি নম্বরটি নেতিবাচক কিনা তা চিহ্নিত করার জন্য সংরক্ষিত এবং অন্য সাতটি বিট প্রস্থকে নির্দেশ করে। এটি char-127 থেকে 127 এর পরিসীমা দেয় যা কেবল 255 অনন্য মান values (কারণ আপনি -0 উপস্থাপনের জন্য একটি দরকারী বিট সংমিশ্রণ হারাবেন))

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

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

সুতরাং এটি একটি যা আপনি সন্ধান করছেন তার বিপরীতে সাজান কারণ এটি পূর্বে ভুলটিকে অত্যধিক মর্যাদাবান কোডকে একটি পূর্ববর্তী সমাধান দেয়।


ট্রাইগ্রাফ অংশটি এই প্রশ্নের উত্তর নয় - এটি নিরব পরিবর্তন নয় not এবং, আইআইএনএম, দ্বিতীয় অংশটি হ'ল কঠোরভাবে বাধ্যতামূলক আচরণের জন্য প্রয়োগকরণ-সংজ্ঞায়িত পরিবর্তন, যা আমি যা জিজ্ঞাসা করেছি তাও নয়।
einpoklum

10

আপনি যদি এটিকে সঠিক কোডের একটি ব্রেকিং পরিবর্তন বিবেচনা করেন তবে আমি নিশ্চিত নই, তবে ...

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

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


4
আমি ভেবেছিলাম এই "প্রয়োজনীয়তা" সি ++ 17 এ যুক্ত হয়েছিল, সি ++ 11 নয়? ( অস্থায়ী
বস্তুকরণ

@ সিডিউউই: আমি মনে করি আপনি ঠিক বলেছেন আমি যখন এটি লিখেছিলাম তখন আমার কাছে স্ট্যান্ডার্ড ছিল না এবং সম্ভবত আমার কিছু অনুসন্ধানের ফলাফলগুলিতে আমি খুব বেশি আস্থা রেখেছিলাম।
অ্যাড্রিয়ান ম্যাকার্থি

বাস্তবায়ন-সংজ্ঞায়িত আচরণের পরিবর্তন এই প্রশ্নের উত্তর হিসাবে গণনা করে না।
einpoklum

7

একটি প্রবাহ থেকে ডেটা পড়ার সময় এবং সংখ্যাটি পড়তে ব্যর্থ হওয়ার আচরণটি c ++ 11 সাল থেকে পরিবর্তিত হয়েছিল।

উদাহরণস্বরূপ, একটি স্ট্রিম থেকে পূর্ণসংখ্যা পড়া, যখন এটিতে কোনও পূর্ণসংখ্যা থাকে না:

#include <iostream>
#include <sstream>

int main(int, char **) 
{
    int a = 12345;
    std::string s = "abcd";         // not an integer, so will fail
    std::stringstream ss(s);
    ss >> a;
    std::cout << "fail = " << ss.fail() << " a = " << a << std::endl;        // since c++11: a == 0, before a still 12345 
}

যেহেতু সি ++ 11 পড়ার পূর্ণসংখ্যাকে 0 এ সেট করবে যখন এটি ব্যর্থ হয়; সি ++ <11 এ পূর্ণসংখ্যার পরিবর্তন করা হয়নি। এতে বলা হয়েছে, সিসিএস, এমনকি মানটি সি ++ 98 (স্ট্যান্ড = সি ++ 98 সহ) ফিরিয়ে দেওয়ার ক্ষেত্রে সর্বদা কমপক্ষে সংস্করণ 4.4.7 থেকে নতুন আচরণ দেখায়।

(ইমো পুরানো আচরণটি আসলে আরও ভাল ছিল: কেন মানকে 0 এ পরিবর্তন করবেন, যা নিজেই বৈধ, যখন কিছুই পড়া যায় না?)

তথ্যসূত্র: https://en.cppreferences.com/w/cpp/locale/num_get/get দেখুন


তবে রিটার্ন টাইপ সম্পর্কে কোনও পরিবর্তন উল্লেখ করা হয়নি। সি ++ 11 সাল থেকে মাত্র 2 টি নিউজ ওভারলোড উপলব্ধ
Build

এই সংজ্ঞায়িত আচরণটি সি ++ 98 এবং সি ++ 11 এ উভয়ই ছিল? নাকি আচরণ সংজ্ঞায়িত হয়ে গেল?
einpoklum

সিপ্রেফারেন্স.কম যখন সঠিক: "যদি কোনও ত্রুটি দেখা দেয় তবে ভি অপরিবর্তিত রেখে দেওয়া হয় (
ড্যানরচেটসফ

আমার বোঝার জন্য, ss এর জন্য আচরণটি প্রকৃতপক্ষে সংজ্ঞায়িত করা হয়েছিল, তবে আপনি যে সাধারণ ক্ষেত্রে অনির্দিষ্টকরণের পরিবর্তনশীল পড়ছেন সেখানে সি ++ 11 আচরণ একটি অবিচ্ছিন্ন ভেরিয়েবল ব্যবহার করবে, যা অনির্ধারিত আচরণ। সুতরাং খুব সাধারণ অপরিজ্ঞাত আচরণের বিরুদ্ধে ব্যর্থতা রক্ষীদের উপর ডিফল্ট-নির্মাণ।
রাসমুস দামগার্ড নীলসেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.