سؤال

جربت الرمز التالي:

#include <iostream>
using std::cout;
using std::ostream;

class X
{
public:
    friend ostream& operator<<(ostream &os, const X& obj) 
    {
        cout << "hehe";          // comment this and infinite loop is gone
        return (os << obj);
    }
};

int main()
{
    X x;
    cout << x;
    return 0;
}

عندما أقوم بتجميع هذا ، فهو كما هو متوقع ؛ حلقة لانهائي. إذا قمت بإزالة cout بيان داخل وظيفة الصديق ، لا يحدث التكرار. لماذا هو كذلك؟

هل كانت مفيدة؟

المحلول

يقرر Optimizer أن كل نشاطك المتبقي ليس له أي تأثير ويقوم بتحسينه بعيدًا. سواء كان الأمر صحيحًا أو خطأ أمر مختلف.

خاصه:

X x;

يخلق كائن فارغ "x"

cout << x;

المكالمات:

return (os << obj);

وهو إلحاق كائن فارغ ؛ يلاحظ برنامج التحويل البرمجي "OS" أي شيء منذ آخر مكالمة ولا يظهر أي وعد في القيام بذلك أكثر (ولا شيء آخر يحدث) ، لذلك يقرر أن النشاط التجاري بأكمله لا لزوم له ويمكن اقتطاعه في هذه المرحلة.

في حالة الاتصال

    cout << "hehe";          // comment this and infinite loop is gone

هناك بعض النشاط الإضافي بحيث لا يزيل المُحسّن المكالمة التالية.

أعتقد أنه إذا تم تهيئته x مع أي شيء غير فارغ ، أو أجرى أي نشاط غير فائق بخلاف cout << "hehe";, ، سيكون لديك عودة تعمل بنفس الشيء.

نصائح أخرى

في كلتا الحالتين (مع وبدون كتابة "Hehe") Visual Studio 2005 يعطي التحذير التالي:

warning C4717: 'operator<<' : recursive on all control paths, function will cause runtime stack overflow

في كلتا الحالتين ، يجمع وفي كلتا الحالتين فائض مكدس.

ومع ذلك ، بدون "Hehe" ، يحدث فائض المكدس في وقت أقرب قليلاً.

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