トップページ > 過去ログ > 記事閲覧
Release時のSetDrawScreen()の挙動
名前:ワラビムシ 日時: 2012/03/10 02:46

この度、書きためたプログラムを試しにReleaseモードでビルドしたところ、Debug時にはなかったエラーが出ていたため質問をさせて頂きました。 開発環境はVisual C++ 2010 Express、DxLib ver3.07aを使用しております。 エラーが確認された最小単位でのソースは以下になります。 #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){ if( ChangeWindowMode( TRUE ) //デフォルトではウィンドウモード + SetGraphMode( 500, 500, 32) //ウィンドウモード: フルカラー + SetDrawMode( DX_DRAWMODE_BILINEAR ) //描画モードセット + DxLib_Init() //初期化 + SetAlwaysRunFlag( TRUE ) //非アクティブでも動作 + SetDrawScreen( DX_SCREEN_BACK ) //裏画面描画モード //↑恐らくここでエラー < 0 ){ DrawString( 0 , 0 , "DXLib初期化中に何らかのエラーが発生しました" , GetColor( 255, 255, 255 )) ; ScreenFlip(); WaitKey(); } DrawString( 0 , 20 , "終了" , GetColor( 255, 255, 255 )) ; ScreenFlip(); ProcessMessage(); WaitKey(); return 0; } Debugビルド時は通常終了となったのですが、Releaseビルド時には「DXLib初期化中に何らかのエラーが発生しました」と表示されます。 + SetDrawScreen( DX_SCREEN_BACK ) の行をコメントアウトすることで一応エラーは解消されるのですが…… ビルド構成を変えることでSetDrawScreen() の挙動が変化する場合はどういった問題が考えられるのか、宜しければご教授頂けないでしょうか。 初歩的な質問で申し訳ありませんが、何卒よろしくお願いいたします

Page: 1 |

Re: Release時のSetDrawScreen()の挙動 ( No.1 )
名前:管理人 日時:2012/03/11 02:59

最適化無しの Debugビルドでは + で繋げた関数呼び出しは左( 上 )から順に 実行されると思いますが、言語の仕様としてはその( 左( 上 )から順に実行される ) 保証はなかったはずです 実際に if文にブレイクポイントを張ってどの順番で関数が呼ばれるか確認してみたところ 1.SetGraphMode( 500, 500, 32) 2.ChangeWindowMode( TRUE ) 3.SetDrawMode( DX_DRAWMODE_BILINEAR ) 4.SetAlwaysRunFlag( TRUE ) 5.SetDrawScreen( DX_SCREEN_BACK ) 6.DxLib_Init() の順番で呼び出されていました ( DxLib_Init の前で呼び出された SetDrawScreen で -1 が返っていました ) 「足し算で繋げられた各要素を左( 上 )から評価( 実行 )する」という仕様がC言語にないので、 Releaseビルドの最適化によって上記のような順番になったのだと思います ( 上記の順番が速度面で有利だから上記の順番になったのか、それとも最適化アルゴリズムの都合で たまたま上記の順番になっただけかはわかりません・・・ ) なので、実行順序が変化しては不都合がある処理を + で繋げるのは避けるようにしてください
Re: Release時のSetDrawScreen()の挙動 ( No.2 )
名前:ワラビムシ(解決) 日時:2012/03/12 13:16

なるほど、言語仕様そのものが問題だったというわけですね。 勉強になります。 お忙しい中、迅速なご回答をありがとうございました。
Re: Release時のSetDrawScreen()の挙動 ( No.3 )
名前: 日時:2012/03/12 13:34

ワラビムシさん、こんにちは。 if文をなるべく減らしたい気持ちはよくわかります。 自分もよくやるのですが、この場合は単純にint型の変数に代入するだけで解決できると思います。 ただ心配なのは、この場合だと、 正常終了:0 エラー:負数 の場合でないと成立しません。 「!=0」にするなど、調整が必要だと思います。

Page: 1 |