2011-10-25 34 views
0

オーバーロード演算子<<返すのostream&

ostream& operator<< (ostream& os, const ReferenceTest& rt) 
{ 
    os << rt.counter; //In this scenario, rt has a public int called counter 
} 

私はこのコードでは、GCC 4.6.1を使用して問題なくコンパイルされたことを知って驚きました。それは私が予想した理由、すなわち私がostreamへの参照を返さないという理由でVisual Studio 2010を使用すると失敗します。しかし、2つのプラットフォーム用にコンパイルされたときのプログラムの出力は同じです(私はテスト出力を書きます)。

どの規格に準拠していますか?私はここで何かを見逃していますか?

-Derek

+0

ありがとうございます。任意の(非voidの)関数から何かを返さなければ、コンパイル時のエラーとみなされませんか?私はこれが警告以上の理由を正当化すると考えていたでしょう。しかし、約同意した。 –

+0

また、実行時の振る舞いは、巧妙なコンパイル(デビッドが示唆したように)、または偶然(K-バロ)の結果ですか?私のコードを実際に "修正"しようとすると、境界を越えて境界線を接しているようです... –

+0

良いコンパイラは、問題を検出したときにコードを修正することを非常に難しくします。これは未定義の動作です。悪いコンパイラは何もしない、何も言わないかもしれない。不快なコンパイラは、 'degauss_hard_drive()'への呼び出しを挿入し、何も言わないかもしれません。定義されていない動作とは、コンパイラがコードを拒否したり、コードを拒否したり、コードを「修正」したり、コードを含むドライブを取り出したりすることです。定義されていない動作に対するコンパイラの応答については、何も問題ありません。 –

答えて

2

警告を有効にしてコンパイルしましたか? g ++でwarning: control reaches end of non-void functionを取得します。

コンパイラがコード内の最初のエラーで停止しないようにしてください。あなたはそれを1つの盛り上がりの中でできる限り多く捉えたいと思っています。これを行うには、コンパイラはあなたのバグのあるコードをパッチしなければならないようにする必要があります。この場合、パッチは明白です:引数として与えられたストリームを返します。

コンパイラによって無料で提供されたこれらの「修正プログラム」は信頼できません。彼らは無料ですが何でもあります。代わりにコードを修正してください。

常に警告を有効にしてコンパイルしてください。

1

return文以外の何かが足りませんか?その欠如は未定義の振る舞いです(私はそれがそのような単純なケースのコンパイル時エラーであると予想します)。 os << rt.counterからの戻り値は、operator<<の戻り値が期待されるのと同じ場所に配置され、ちょうどうまく動作することがあります。

+0

これは未定義の動作であることは間違いありません。何らかの理由で、GNUスイートは非空白関数の終わりに、コミコミルエラーではなく単なる警告に値すると考えています。いくつかの戻り値を構成し、コンパイル時に押す。 –

+0

@David Hammen:関数が関数の終わりに達する可能性があるかどうかを確認することは、かなり複雑な解析です。標準では「診断は必要ありません」と言われています。 –

+0

「診断不要です」と言う理由はありません。 6.6。3 para 2: "関数の終わりからの流れは、値のない戻り値と同じです;これは、値を返す関数で未定義の振る舞いになります。"未定義の動作には診断は必要ありません。これは、コンパイラがUBを検出したときに、それが静かでなければならないこと、またはコンパイラがコンパイルされたコードを発行しなければならないことを意味しません。コンパイラのエラーとして最後から流れ落ちることは完全にOKです。 –

関連する問題