こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

最適化したプログラムによる計算時の問題(GCC)

GCC(4.4.1)で曲線を数値積分して長さを求めるプログラムを作っています。
double totalLength;
for(j = 1; j < d; j++)
{
::: ここでdx,dyを計算
totalLength += sqrt(dx * dx + dy * dy);
}
printf("%f\n", totalLength);
これをOptimize3でコンパイル、実行するとtotalLengthがデタラメで巨大な結果だったので、
以下のようにして細かく分析しようとしました。
for(j = 1; j < d; j++)
{
::: ここでdx,dyを計算
totalLength += sqrt(dx * dx + dy * dy);
printf("%f\n", totalLength); //for内に入れる。
}
このようにすると、他の部分を操作していないにもかかわらず、期待通りのtotalLengthとなりました。
そこで
for(j = 1; j < d; j++)
{
::: ここでdx,dyを計算
totalLength += sqrt(dx * dx + dy * dy);
printf("");
}
とすると、やはり期待通りの結果となります。
sqrt関数はどちらの場合も正しい結果を返しているようです。
なぜprintfがないときは正しく加算されず、printfが存在する時は正しい結果となるのでしょうか。
また、Optimize1でコンパイルした場合はprintfしなくても正しい結果となります。
これはGCCのバグですか

投稿日時 - 2009-11-29 09:36:53

QNo.5484351

vbk

困ってます

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

単に、

double totalLength = 0;

――と、初期化し忘れてるだけだったりして。

投稿日時 - 2009-11-29 11:54:53

ANo.2

#1 に完全に同意. 隠れている「ここで dx, dy を計算」の内容が分からないので原因は分かりません.

投稿日時 - 2009-11-29 11:29:54

ANo.1

提示されている情報だけでGCCのバグかどうかを断定できる人はいないでしょう。
もしかすると、省略されているコードの中でメモリを破壊するようなことをしているのかもしれないわけで。
gccの-Sオプションで出力されるアセンブラファイルの該当部分を最適化レベル別に見比べてみてください。

投稿日時 - 2009-11-29 11:16:32

補足

回答ありがとうございました。
省略部分が多くてすみません。
ただ、最適化のレベルを低くすると正しい値となるので、プログラムそのものには問題がないと思います。
アセンブラの確認まではしませんでしたが、変数の前にvolatileをつけたら誤差が大きいもののほぼ正しい値となりました。
根本的な解決とはなりませんでしたが、最適化回避の方向で進めようと思います。

投稿日時 - 2009-11-29 15:42:12

あなたにオススメの質問