25

VS2012 を使用しswitchて、数年間動作していた a がリリース ビルドでは壊れているように見えますが、デバッグ ビルドでは正しく (または少なくとも以前と同じように) 動作することに気付きました。コードに問題はまったく見られないので、ブロックreturn内からステートメントを使用することの正確さについてのフィードバックをいただければ幸いです。switch

次のコードは正常にコンパイルされますが、Win7 32 ビットのリリース ビルドでは間違った出力が得られます...

#include <stdio.h>
#include <tchar.h>

class CSomeClass
{
public:
    float GetFloat(int nInt)
    {
        printf("GetFloat() - entered\n");
        switch (nInt)
        {
        case 1 :
            printf("GetFloat() - case 1 entered\n");
            return 0.5F;
        case 0 :
            printf("GetFloat() - case 0 entered\n");
            return 1.0F;
        case 2 :
            printf("GetFloat() - case 2 entered\n");
            return 2.0F;
        case 3 :
            printf("GetFloat() - case 3 entered\n");
            return 3.0F;
        case 4 :
            printf("GetFloat() - case 4 entered\n");
            return 4.0F;
        }
        printf("GetFloat() - exit\n");
        return 1.0F;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    CSomeClass pClass;
    float fValue = pClass.GetFloat(3);
    printf("fValue = %f\n", fValue);

    return 0;
}

問題を繰り返すことができ、MS Connect にログインできる場合は、ここでも投票できますか?

実績

リリース ビルドでは、次の誤った結果が得られます。

GetFloat() - entered
GetFloat() - case 3 entered
fValue = 0.000000

予想された結果

デバッグ ビルドでは、次の正しい結果が得られます。

GetFloat() - entered
GetFloat() - case 3 entered
fValue = 3.000000

MS Connect バグ レポート

4

3 に答える 3

7

このバグのようですね。同様の方法で生成された浮動小数点値を返す際に問題があるのはどこですか?

于 2013-02-12T15:34:54.233 に答える
6

間違いなくコンパイルエラーです。これは、実行中の asm コードを削除したものです (ジャンプなどは削除されています)。コンパイラは、不要であるにもかかわらず、不要であると想定する一部のコードを削除します。


リリース ビルド:

// inside GetFloat
00E0104D  fld         dword ptr ds:[0E021D8h]  // load constant float onto FPU stack
00E01068  add         esp,4
00E0106B  ret 
// back in main
00E01098  cvtss2sd    xmm0,xmm0  // convert float to double. assumes the returned value to be in xmm0
00E0109C  sub         esp,8  
00E0109F  movsd       mmword ptr [esp],xmm0  // push double being printed (xmm0 is with high likelyhood = 0)
00E010A4  push        0E021B8h   // push output string
00E010A9  call        dword ptr ds:[0E02090h]  // call printf

デバッグ ビルド:

003314B0  fld         dword ptr ds:[335964h]   // load const float onto FPU stack
[...]
00331500  mov         esp,ebp  
00331502  pop         ebp  
00331503  ret         4  
// back in main
00331598  fstp        dword ptr [fValue]  // copies topmost element of the FPU stack to [fValue]
0033159B  cvtss2sd    xmm0,dword ptr [fValue] // correctly takes returned value (now inside [fValue] for conversion to double 
003315A0  mov         esi,esp  
003315A2  sub         esp,8  
003315A5  movsd       mmword ptr [esp],xmm0  // push double being printed
003315AA  push        335940h  // push output string
003315AF  call        dword ptr ds:[3392C8h]  // call printf
于 2013-02-12T15:44:46.140 に答える
5

すべての結果からデータを収集すると、おそらくコンパイラのバグです。

  • x64 は正しく動作します
  • /O1正しく動作します
  • まあ、Debug正しく動作します
  • coutとの両方で同じ種類のエラーが発生しますprintf

そして、おそらく最も重要なことは、100% 標準に準拠していることです。だからうまくいくはずです。

于 2013-02-12T15:11:39.537 に答える