سؤال

يتضمن خيار G ++ -WALL -Wreorder. ما يسميه هذا الخيار أدناه. ليس من الواضح بالنسبة لي لماذا يهتم شخص ما (خاصة بما يكفي لتشغيل هذا بشكل افتراضي في -Wall).

-Wreorder (C ++ فقط) يحذر عندما لا يتطابق ترتيب تهيئة الأعضاء الواردة في التعليمات البرمجية مع الطلب الذي يجب تنفيذه فيه. على سبيل المثال: بنية {int i؛ Int J؛ a (): j (0)، i (1) {}}؛ سيقوم المحول البرمجي بإعادة ترتيب مهنيات الأعضاء ل I و J لتتناسب مع أمر الإعلان للأعضاء، تنبعث منه تنبعث منهذا تحذيرا بهذا المعنى. يتم تمكين هذا التحذير من قبل.
هل كانت مفيدة؟

المحلول

انصح:

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

حاليا i تتم تهيئتها إلى بعض القيمة غير المعروفة، وليس الصفر.

بدلا من ذلك، تهيئة i قد يكون لها بعض الآثار الجانبية التي يكون النظام مهم. على سبيل المثال

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

نصائح أخرى

المشكلة هي أن شخصا ما قد يرى قائمة مهاجري الأعضاء في المنشئ، ويعتقدون أنهم ينفذون بهذا الترتيب (ي أولا، ثم أنا). إنهم ليسوا كذلك، يتم تنفيذها بالترتيب الذي يتم تعريف الأعضاء في الفصل.

لنفترض أنك كتبت A(): j(0), i(j) {}. وبعد قد يقرأ شخص ما، وأعتقد أني ينتهي بك الأمر إلى القيمة 0.ه لا، لأنك أهتم به مع J، والذي يحتوي على غير المرغوب فيه لأنه لم يتم تهيئة نفسها.

تحذير يذكرك بالكتابة A(): i(j), j(0) {}, ، والتي نأمل أن تبدو أكثر مريبا.

قدمت إجابات أخرى بعض الأمثلة الجيدة التي تبرر خيار التحذير. اعتقدت أنني سأقدم بعض السياق التاريخي. يشرح خالق C ++، Bjarne Stroustrup، في كتابه لغة البرمجة C ++ (الطبعة الثالثة، صفحة 259):

يتم استدعاء منشئ الأعضاء قبل تنفيذ نص المنشئ حسب الفئة المحتوية. يتم استدعاء المنشئين بالترتيب الذي يتم فيه الإعلان عنها في الفصل بدلا من الترتيب الذي تظهر به في قائمة المهنة. لتجنب الارتباك، من الأفضل تحديد المهيمين في أمر الإعلان. يتم استدعاء المدمرين الأعضاء في الترتيب العكسي للبناء.

هذا يمكن أن يعضك إذا كان لدى المهيئين من الآثار الجانبية. انصح:

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

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

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

سيقوم أعلاه بطباعة "Bar" ثم "Foo"، على الرغم من أن المرء بشكل حدسي من شأنه أن يفترض أن الطلب هو مكتوب في قائمة المهنة.

بدلا من ذلك، إذا x و y هي من بعض أنواع المعرفة من قبل المستخدم مع منشئ، قد يكون لهذا المنشئ أيضا آثارا جانبية، مع نفس النتيجة غير الواضحة.

يمكن أن يظهر أيضا عندما يشير تهيئة عضو واحد إلى عضو آخر.

يوجد تحذير لأنه إذا قرأت المنشئ، فهذا يبدو j يتم تهيئة من قبل i. وبعد يصبح هذا مشكلة إذا تم استخدام أحد لتهيئة الآخر، كما هو الحال في

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

عندما تنظر فقط إلى المنشئ، هذا تبدو آمنة. ولكن في الحقيقة، j لم تتم تهيئته بعد عند النقطة التي يتم فيها استخدامها في التهيئة i, ، وبالتالي لن يعمل الكود كما هو متوقع. ومن هنا تحذير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top