1
1

More than 5 years have passed since last update.

printf debugしてドツボにはまった話

Posted at

標準出力に値を出しながらデバッグをする、いわゆるprintf debugしてた時の話です。
こんなソースが有りました。

void move(){
    std::cout << player.move() << std::endl;
}

move()はプレイヤの座標を移動させる関数です。
普段は0を返しますが、壁にあたったりしてmove()が失敗すると1を返すわけです。
で、壁にあたってないのに1を返したり、移動してないのに0を返したりと
move()の動作がどうもおかしいので、返り値を表示するようにしています。
また、移動後の座標も一緒に表示するようにしました。

void move(){
    std::cout << player.move() << "(" << player.getx() << "," player.gety() << ")" << std::endl;
}

予想通り座標もおかしい。
で、調べていましたが、何故か違和感が…。

先ほどのコードはmove()を実行した後の座標がほしいわけなのですが、
何故かmove()を実行する前の座標が表示されているようです。

気がついた人はいると思いますが、この書き方は未定義動作を含みます。
具体的には、move(),getx(),gety()はどの順序で呼び出されるかわかりません。
言語仕様としては、実装依存、ということですね。

副作用のある関数(内部状態を変更する関数)は単独で使うようにしましょう。
よって、こういう風に書き換えると想定通りに動きました。

void move(){
    auto moveresult = player.move();
    std::cout << moveresult << "(" << player.getx() << "," player.gety() << ")" << std::endl;
}

move()のバグはまだとれてません。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1