জি ++-ওয়ারর্ডারের বিন্দুটি কী?


150

জি ++ -ওয়াল বিকল্পটিতে -উর্ডার অন্তর্ভুক্ত রয়েছে। এই বিকল্পটি যা করে তা নীচে বর্ণিত। কেউ কেন যত্ন নেবে তা আমার কাছে স্পষ্ট নয় (বিশেষত-ওয়াল-এ ডিফল্টরূপে এটি চালু করার পক্ষে যথেষ্ট)।

ওয়ারর্ডার (কেবলমাত্র সি ++)
  কোডটিতে প্রদত্ত সদস্য প্রারম্ভিকদের অর্ডার না দিলে সতর্ক করুন
  ক্রমটি মেলান যাতে তাদের অবশ্যই সম্পাদন করা উচিত। এই ক্ষেত্রে:

    কাঠামো এ {
      int i;
      int j;
      ক (): জ (0), i (1)}
    };

  সংকলকটি আমি এবং জেতে সদস্য প্রারম্ভিকদের পুনর্বিন্যাস করবে
  সদস্যদের ঘোষণার আদেশের সাথে মেলে, এটিকে সতর্কতা নির্ধারণ করুন
  প্রভাব। এই সতর্কতা -ওয়াল দ্বারা সক্ষম করা হয়েছে।

2
এখানে কিছু ভাল উত্তর, তবে এটি যে কারওর আগ্রহের ক্ষেত্রে একটি সংক্ষিপ্ত দিকে বাদ দিলে: g ++ এর পুরো পতাকাটি ত্রুটি হিসাবে বিবেচনা করার জন্য একটি পতাকা রয়েছে:-Werror=reorder
ম্যাক্স ব্যারাক্লফ

উত্তর:


257

বিবেচনা:

struct A {
    int i;
    int j;
    A() : j(0), i(j) { }
};

এখন iশূন্য নয়, কিছু অজানা মান থেকে শুরু করা হয়েছে।

বিকল্পভাবে, আরম্ভের ক্ষেত্রে iকিছু পার্শ্ব প্রতিক্রিয়া থাকতে পারে যার জন্য ক্রমটি গুরুত্বপূর্ণ। যেমন

A(int n) : j(n++), i(n++) { }

80
ডকুমেন্টেশনে এটি সত্যই উদাহরণ হওয়া উচিত।
বেন এস

3
ধন্যবাদ। আমাদের প্রকারের বেশিরভাগ সাধারণ প্রারম্ভিকগুলির সাথে পিওডি টাইপ হওয়ায় এটি আমার কাছে ঘটেনি। আপনার উদাহরণটি জি ++ ম্যানুয়াল উদাহরণের চেয়ে অনেক ভাল।
পিটার জুট

5
@ মাইকটি হ'ল কারণ আপনার সংকলক (জিসিসি) অবিচ্ছিন্ন ভেরিয়েবলগুলি 0 থেকে শুরু করে, তবে এটি এমন কিছু নয় যা আপনার উপর নির্ভর করা উচিত; আমি 0 হচ্ছে
অবিচ্ছিন্ন

2
@ ইয়াক্ক অর্ডারটি ম্যান পেজ-> উত্তর ছিল। এখানে 2007 সালের ম্যান পৃষ্ঠার একটি সংরক্ষণাগার রয়েছে যা এই উদাহরণটিকে স্পষ্টভাবে তালিকাভুক্ত করে। বেন এস এর আপত্তিজনক মন্তব্যটি এমন একজনের হাস্যকর উদাহরণ যা কেউ পরামর্শ দিয়েছিল যে এটি ইতিমধ্যে আছে কিনা তা পরীক্ষা করেও কিছু উপস্থিত রয়েছে। web.archive.org/web/20070712184121/http://linux.die.net/man/1/…
কিমিকোলোকে

3
এই টুইটটি নিখুঁত ভুল @ ম্যান পৃষ্ঠায় উদাহরণটি ওপি থেকে পাওয়া একটি (যেখানে iপ্রাথমিককরণ হয় 1)। এখানে, iএর সূচনা করা হয়েছে j, যা আসলে কোনও সমস্যা দেখায়।
jazzpi

42

সমস্যাটি হ'ল কেউ হয়ত নির্মাতার সদস্য প্রাথমিকের তালিকা দেখতে পারে এবং মনে করে যে তারা এই ক্রমে কার্যকর করা হয়েছে (জে প্রথমে, তারপরে আমি)। তারা নয়, সদস্যদের শ্রেণিতে নির্ধারিত ক্রমে তারা কার্যকর করা হয়।

ধরুন আপনি লিখেছেন A(): j(0), i(j) {}। যে কেউ এটি পড়তে পারে এবং মনে করতে পারে যে আমি 0 মান দিয়ে শেষ করছি It এটি নয়, কারণ আপনি এটি জে দিয়ে শুরু করেছিলেন, এতে জাঙ্ক রয়েছে কারণ এটি নিজেই আরম্ভ করা হয়নি।

সতর্কতা আপনাকে লেখার জন্য মনে করিয়ে দেয় A(): i(j), j(0) {}, যা আশাকরি আরও অনেক মাছরাশি দেখায়।


দেখায় / দুর্গন্ধযুক্ত সত্যই! :) অবশ্যই কোড গন্ধ :) আপনার স্পষ্ট ব্যাখ্যার জন্য ধন্যবাদ যে পয়েন্টটি ঠিক আছে। :)
উইল

1
"... আপনাকে এ () লিখতে স্মরণ করিয়ে দেয়: i (জে), জে (0) {} ..." আমি পরামর্শ দিচ্ছি যে এটি আপনাকে বিশেষ ক্ষেত্রে শ্রেণীর সদস্যদের পুনরায় অর্ডার করার জন্য মনে করিয়ে দেয়।
2.718

18

অন্যান্য উত্তরগুলি কয়েকটি ভাল উদাহরণ সরবরাহ করেছে যা সতর্কতার বিকল্পটিকে ন্যায়সঙ্গত করে। আমি ভেবেছিলাম আমি কিছু historicalতিহাসিক প্রসঙ্গ সরবরাহ করব। সি ++ এর স্রষ্টা, বাজার্ন স্ট্রস্ট্রপ তাঁর দ্য সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজে (তৃতীয় সংস্করণ, পৃষ্ঠা 259) ব্যাখ্যা করেছেন:

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


10

আপনার প্রারম্ভিকদের পার্শ্ব প্রতিক্রিয়া থাকলে এটি আপনাকে কামড় দিতে পারে। বিবেচনা:

int foo() {
    puts("foo");
    return 1;
}

int bar() {
    puts("bar");
    return 2;
}

struct baz {
    int x, y;
    baz() : y(foo()), x(bar()) {}
};

উপরেরগুলি "বার" তারপরে "foo" মুদ্রণ করবে, তবুও স্বজ্ঞাতভাবে কেউ অনুমান করবে যে আদেশটি প্রাথমিকভাবে তালিকায় লেখা আছে is

বিকল্পভাবে, যদি xএবং yকোনও নির্মাণকারীর সাথে কিছু ব্যবহারকারী-সংজ্ঞায়িত প্রকারের হয় তবে সেই নির্মাতারও একই অ-সুস্পষ্ট ফলাফলের সাথে পার্শ্ব প্রতিক্রিয়া থাকতে পারে।

এটি যখন নিজেই প্রকাশ পায় যখন কোনও সদস্যের জন্য আরম্ভকারী অন্য সদস্যকে উল্লেখ করে।


7

সতর্কতা উপস্থিত রয়েছে কারণ আপনি যদি কেবল কন্সট্রাক্টরটি পড়ে থাকেন তবে মনে jহয় এর আগে আরম্ভ হচ্ছে i। এটি যেমন সমস্যা হিসাবে দেখা দেয় যদি অন্যটি আরম্ভ করার জন্য অন্যটিকে ব্যবহৃত হয়

struct A {
  int i;
  int j;
  A(): j (0), i (this->j) { }
};

আপনি যখন কেবল কনস্ট্রাক্টরের দিকে তাকান, এটি নিরাপদ দেখায় । তবে বাস্তবে, jএখনও যে পর্যায়ে এটি আরম্ভ করার জন্য ব্যবহৃত হয় তা আরম্ভ করা হয়নি iএবং সুতরাং কোডটি প্রত্যাশার মতো কাজ করবে না। সুতরাং সতর্কতা।

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