我在Windows 8 64位上使用Visual Studio 2012。 我有这两种方法:
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将被更新” - “NODE将不会更新”。 造成这种情况的原因是什么?
答案 0 :(得分:2)
SCALING
是一个32位有符号整数,其值为0x20
。您将1
移位0x20
(32)位。这意味着你将它移得太远,导致未定义的行为。
标准的相关引用:
E1的结果&lt;&lt; E2是E1左移E2位位置;腾出的位用零填充。如果E1具有无符号类型,则结果的值为E1×2E2,比结果类型中可表示的最大值减少一个模数。 如果E1具有带符号类型和非负值,并且E1×2E2在结果类型中可表示,那么这就是结果值;否则,行为未定。
答案 1 :(得分: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;
}
答案 2 :(得分: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(或&amp; = ~state)。同样,getState应该只返回states_&amp;状态。