9

さて、私はIdeoneをいじり回していて、誤ってこのコードを送信しましたが、驚いたことに、実際にコンパイルされて実行され、ここで値0が出力されました。

#include <iostream>

using namespace std;

const int five(  )
{
        const int i = 5;
}

int main() {
        cout << five(  ) << endl;
        return 0;
}

次に、これをVisual Studioで試しましたが、Codepadfive()で、期待どおりに値が返されないため、両方ともコンパイルに失敗しました。もちろん、私の質問は、コードが間違っていてコンパイルすべきではないのに、なぜこれがIdeoneで正常にコンパイルされるのかということです。

4

4 に答える 4

14

単純明快(C ++ 11 6.6.3「returnステートメント」から):

関数の終わりから流れ出るのは、値のない戻りと同じです。これにより、値を返す関数で未定義の動作が発生します。

したがって、コンパイラはほとんど何でもやりたいことができます。明らかに、診断はコンパイラーに求めるものですが、診断が難しい場合があります(たとえば、戻り値が条件付きロジック内にあり、関数の「終了」に到達しない場合など)。

WallGCC 4.6.1(オプションを使用)で次の警告が表示されることに注意してください。

test.cpp:8:1: warning: no return statement in function returning non-void [-Wreturn-type]

ideoneがGCCに渡すオプションがわかりません(-Wallideoneが使用する4.3.4バージョンでも同じことができると思います)。

いくつかの関連情報:

Cでは、値を返すように宣言されている関数が、特定の状況では実際には返さないようにしても問題ありません。Cでは、関数の戻り値が実際に使用された場合にのみ、未定義の動作が発生します。以前の標準Cは常にvoid型をサポートしていなかったため、何も返さない関数はint、明示的または暗黙的に、を返すように宣言されることがよくありました。C99から6.9.1/12「関数定義」:}関数を終了するに到達し、関数呼び出しの値が呼び出し元によって使用される場合、動作は未定義です。

また、いくつかのコメントで述べたように、の終わりから流れることは、main()C++およびC99以降によって特別に扱われます。

于 2012-07-15T20:22:06.807 に答える
3

void以外の関数から値を返さないのは間違いですが、すべてのコンパイラがそれをエラーとして扱うわけではありません。たとえば、GCCはこれに遭遇したときにのみ警告を出します。他のコンパイラーはパラノイアであり(そしてそれらは正しい)、そのようなコードをコンパイルさせないかもしれません。もちろん、コンパイラの動作は、さまざまなスイッチやオプションを使用して変更できます。

0の戻り値は単なるランダムな値です。これは未定義の動作であるため、255、-1、またはその他のガベージになる可能性があります(C99が暗黙の0の戻り値を想定するように指定しているmainを除く) 。

于 2012-07-15T20:23:24.623 に答える
3

ideoneは警告を表示せず、エラーが発生した場合にのみコンパイラ出力を表示するようです。ideoneが使用しているバージョンのGCC(gcc 4.3)では、これはエラーではなく、単なる警告です。

于 2012-07-15T20:23:33.013 に答える
2

コードの動作は未定義です。あなたがしていることが間違っていても、コンパイラはそれを診断する必要はありません。もう1つのポイントは、ideoneが現在かなり古いバージョンのgccを使用していることです。適度に最新のバージョンのgcc(たとえば、4.7)は、少なくとも、関数が値を返すように宣言されているという警告を表示しますが、デフォルトでは返しません。警告を受け取るようなものでオンにする必要-Wallがあります(ただし、原則として、私は常に少なくとも-Wallとgccを使用します)。

于 2012-07-15T20:24:39.537 に答える