1

Windows 8 64 ビットで Visual Studio 2012 を使用しています。私はこれらの2つの方法を持っています:

void Node::setState(States state, bool value) {
    if (value) {
        states_ |= 1 << state;
    }
    else {
        states_ &= ~(1 << state);
    }
}

bool Node::getState(States state) {
    return (states_ & (1 << state)) != 0;
}

状態列挙:

enum States {
    UPDATABLE = 0x01, // Node data update.
    RENDERABLE = 0x02, // Node rendering on screen.
    TRANSFORMABLE = 0x04, // Position, rotation and scaling update.
    POSITION = 0x08, // Position update.
    ROTATION = 0x10, // Rotation update.
    SCALING = 0x20 // Scaling update.
};

ステート整数の初期化:

states_(TRANSFORMABLE | RENDERABLE |
            UPDATABLE | POSITION | ROTATION | SCALING)

問題はコードの次の部分にあります。

LOGI("SETTING SCALING FOR NODE: %s", node->getName().c_str());
node->setState(Node::SCALING, true);
if (node->getState(Node::SCALING)) {
    LOGI("NODE WILL BE UPDATED.");
}
else {
    LOGI("NODE WILL NOT BE UPDATED.");
}

デバッグモードでは「NODE WILL BE UPDATED」、リリース時には「NODE WILL NOT BE UPDATED」が表示されます。これは何が原因ですか?

4

3 に答える 3

2

SCALING値が。の32ビット符号付き整数です0x20。(32)ビット位置だけシフト1したままになります。0x20つまり、シフトしすぎて、未定義の動作が発生します。

標準からの関連する引用:

E1 << E2の結果は、E1の左シフトE2ビット位置です。空になったビットはゼロで埋められます。E1に符号なしタイプがある場合、結果の値はE1×2E2であり、結果タイプで表現可能な最大値よりも1を法として減少します。E1に符号付きタイプと非負の値があり、E1×2E2が結果タイプで表現可能である場合、それが結果の値です。それ以外の場合、動作は定義されていません。

于 2013-03-08T06:35:31.530 に答える
1

の値Statesはビットマスクであり、シフト値ではありません。

値をシフトするように変更します。

enum States {
    UPDATABLE = 0, // Node data update.
    RENDERABLE = 1, // Node rendering on screen.
    TRANSFORMABLE = 2, // Position, rotation and scaling update.
    POSITION = 3, // Position update.
    ROTATION = 4, // Rotation update.
    SCALING = 5 // Scaling update.
};

の初期化をstates_適切に変更します。またはそれらをマスクとして使用します。

void Node::setState(States state, bool value) {
    if (value) {
        states_ |= state;
    }
    else {
        states_ &= ~state;
    }
}

bool Node::getState(States state) {
    return (states_ & state) != 0;
}    
于 2013-03-08T06:38:57.317 に答える
1

states_ は 32 ビット整数だと思います。setState と getState の実装が期待どおりに機能していません。setState(SCALING) は 1 0x20 (= 32) ビットを左にシフトすることに注意してください。32 ビットの整数がある場合、未定義の結果が生成されます ( http://msdn.microsoft.com/en-us/library/336xbhcz(v=vs.71).aspxを参照)。したがって、コード オプティマイザ (おそらくこの場合、デバッグ ビルドとリリース ビルドの重要な違い) は、最適化されていないコードとは異なることを自由に実行できます。

状態の値の定義を考えると、setState は states_ |= state (または &= ~state) にする必要があります。同様に、getState は states_ と state のみを返す必要があります。

于 2013-03-08T06:47:07.533 に答える