2013-04-03 10 views
6
class foo { 
    public: 
    friend ostream& operator << (ostream &os, const foo &f); 
    foo(int n) : a(n) {} 
    private: 
    vector <int> a; 
}; 

ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    os << endl; // why is this line a must? 
} 

int main(void) { 
    foo f(2); 
    cout << f << endl; 
    return 0; 
} 

上記のコードでは、マークされた行が削除されると、セグメントのフォールトエラーが発生します。endstreamがない場合にオーバーロードされたostream演算子のセグメント化エラー

+1

?コンパイラは、このようなエラーについて警告していたはずです - "...警告:非void [-Wreturn-type]を返す関数でreturn文がありません" ^ – SChepurin

答えて

16
ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    os << endl; // why is this line a must? 
} 

はmanadatoryではありません。あなたがのostreamを返していない場合、それは未定義の動作ですos

ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    return os; // Here 
} 

を返すされていないため、セグメンテーションフォルトが発生しています。 endlはここでosをフラッシュしています。それが働いているように見える理由です。

EDIT:なぜそれがこのケースで働いているボーPerssonのに応じ

OS < <てendl; によって実際にosを返す別の演算子呼び出しです。戻り値が期待される場所(おそらくレジスタ)に配置されます。コードがメインに別のレベルを返し は、OSへの参照は ですまだ

誰も問題のコードをチェックするために気にしないのはなぜ
+0

Is何も指定されていない場合、またはその値が何らかの形で標準化されている場合に返される暗黙の 'int'(?) –

+4

暗黙の 'int'はここに返されません。これは 'ostream&'を返すものとして明確に指定されています。したがって、 'return'ステートメントがなければ、関数の後のスタック上の正しい場所に何らかのジャンクが発生します。 'os << endl'があるので、そのジャンクはクラッシュを引き起こさないものです。 – BoBTFish

+2

@honk C++には暗黙の 'int'はありません。 '' void''以外の関数から何かを返さないと、定義されていない動作、期間が発生します。 – Angew

関連する問題