2

次のような関数がある場合:

int addNumbers(int x, int y)
{
    return x + y;
}

そして、私がそれをそのように使用する場合:

cout << addNumbers(4, 5) << endl;

返されて印刷されます9。上記の同じcout行を使用して、 return をコメント アウトするか削除すると、 return が出力されaddNumbersます1。私がこれを行う場合:

int addNumbers(int x, int y)
{
    int answer = x + y;
    //return x + y;
}

9returnを使用しなくても、自動的に return と print が表示されます。同様に、次のように書くことができますint answer = x。そしてそれは戻り4ます。私はこれを書くこともできます:

int addNumbers(int x, int y)
{
    int answer = x;
    answer = 1;
    //return x + y;
}

それでも4が返されます。

正確には何が返され、その理由は何ですか? パラメータ変数を使用すると 1 以外の値しか返されませんが、最後の例に示すように変数 answer は返されません。これは、変数を 1 に変更しても の値が返されたためですx (4)

4

4 に答える 4

3

§6.6.3 [stmt.return]/p2:

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

(main()は特別な例外です。 の末尾からの流出は amain()と同等ですreturn 0;)

許容される UB は次のとおりです。

  • 返してほしいと思ったものを返す
  • 代わりにガベージ値を返す
  • クラッシュ
  • パスワードをハッカーに送信する
  • ハード ドライブのフォーマット
  • コンピューターを爆発させて足を吹き飛ばす
  • 鼻の悪魔を召喚する
  • 時間をさかのぼってプログラムを正しいものに修正する
  • ブラックホールの作成
  • ……

しかし真剣に、UB はあらゆる種類の方法で現れる可能性があります。たとえば、次のコードがあるとします。

#include <iostream>
bool foo = false;
int addNumbers(int x, int y)
{
    int answer = x;
    answer = 1;
    //return x + y;
}

int main(){
  if(!foo) {
    addNumbers(10, 20);
    std::cout << 1 << std::endl;
  }
  else {
    std::cout << 2 << std::endl;
  }
}

-O2でclang ++が出力 2されます。

なんで?の動作は未定義であると推定されたためaddNumbers(10, 20);、最初の分岐は決して行われず、foo常にtrueであると想定できますが、明らかにそうではありません。

于 2014-09-06T08:48:21.397 に答える
1

「未定義の動作」に依存しています。戻り値は、単純型の場合、通常はレジスタに格納され、計算結果の形成にも使用できます。しかし、それは使用されない可能性もあり、任意の「ランダムな」結果が得られ、「未定義の動作」であるため、コンピューターが実行する可能性のある他の操作も発生する可能性があります-クラッシュまたは実行していないコードの実行など実行したい...

于 2014-09-06T08:44:53.633 に答える
0

未定義の動作が観察されています。プログラムが整形式のプログラムではないため、プログラムがそれを行う「理由」の正当な理由はありません。実行時にディスクから自分自身を削除するなど、何でもできます。コンパイラの警告とエラー (例: g++ -Wall -Wextra -Werror) を有効にすると、そのようなコードを書くことは自動的に禁止されます (そうあるべきです)。

于 2014-09-06T08:43:41.780 に答える