【发布时间】:2019-08-12 04:53:56
【问题描述】:
我有 4 张图像要显示,所以我使用 unsigned short 来表示当前图像的索引。当我按 A 时,索引减 1;当我按 D 时,索引增加 1。
我正在使用 image_index = (image_index - 1) % 4; 计算 A 按键上的索引(在 D 按键上,image_index = (image_index + 1) % 4;)
如果我向前循环(IE,按 D),一切都会按预期工作,但如果我在索引 0 并按 A,它会下溢到无符号短整数的最大值,并且不会以 4 为模给我索引 3。
我知道对于有符号类型,上溢/下溢是 UB,但我确信对于无符号类型,它是明确定义的。有什么想法可能导致它忽略模数?
enum class Errors : short {
kSdlSuccess = 0,
kSdlInitFailure = -1,
kSdlWindowCreationError = -2,
kSdlRendererCreationError = -3
};
int main(int argc, char** argv) {
sdl::Context ctx;
sdl::Window window({ .w = 600, .h = 480, .flags = 0});
sdl::Renderer renderer(window, {0});
bool is_running {true};
unsigned short texture_index = 0;
SDL_Event event {};
while(is_running) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) { is_running = false; }
else if(event.type == SDL_KEYDOWN) {
if(event.key.keysym.scancode == SDL_SCANCODE_A) { texture_index = (texture_index - 1) % 4; }
else if(event.key.keysym.scancode == SDL_SCANCODE_D) { texture_index = (texture_index + 1) % 4; }
}
}
printf("%d\n", texture_index);
renderer.setDrawColor(255, 0, 0, 255);
renderer.clearBuffer();
renderer.setDrawColor(0,0,0,255);
renderer.drawTexture(texture_index);
renderer.swapBuffer();
}
return static_cast<int>(Errors::kSdlSuccess);
}
【问题讨论】:
-
试试
texture_index = (texture_index - 1u) % 4u; -
没有整数下溢之类的东西。对于有符号整数,超过任一限制称为溢出。对于无符号整数没有溢出,算术定义为模 (max+1)。无论如何,根据积分提升规则, unsigned short 被提升为 signed int。
-
当然还有 (x-1)%4 == (x+3)%4 所以...
标签: c++ undefined-behavior modulo underflow