【发布时间】:2021-12-31 08:50:44
【问题描述】:
我有以下代码,它可以从 16bpp 图像到 1bpp 图像进行非常基本的转换,代码按预期运行,直到我启用编译器优化,此时我只得到一个黑色图像。
#define RSCALE 5014709
#define GSCALE 9848225
#define BSCALE 1912602
uint16_t _convertBufferTo1bit(uint8_t* buffer, uint16_t size)
{
uint8_t* dst_ptr = buffer;
uint8_t* end_ptr = buffer + size;
uint16_t pos = 0;
uint8_t r, g, b, i;
uint32_t lum;
while(buffer < end_ptr)
{
for(i = 8; i > 0; i--)
{
r = (*buffer & 0xF8);
g = ((*buffer & 0x07) << 5);
buffer += 1;
g |= (*buffer & 0x03);
b = ((*buffer & 0x1F) << 3);
buffer += 1;
lum = ((RSCALE * r) + (GSCALE * g) + (BSCALE * b));
if(lum > 0x7FFFFFFF)
{
//White
dst_ptr[pos] |= (1 << (i-1));
}
else
{
//black
dst_ptr[pos] &= ~(1 << (i-1));
}
}
pos++;
}
return pos;
}
查看反编译的程序集时,我可以看到if(lum > 0x7FFFFFFF) 语句和所有相关计算已被编译器删除。有人可以帮我理解为什么吗?
-O0 -std=c++17 -Wall -Wextra
https://godbolt.org/z/GhPezzh33
-O1 -std=c++17 -Wall -Wextra
【问题讨论】:
-
@RichardCritten 这是一个零终止循环。它应该可以正常工作
-
对不起,你是绝对正确的。发现了别的东西 - 从
lum > 0x7FFFFFFF中删除最后一个F并且代码正确生成 - 仍在调查这个。 -
编译器已确定您无法访问
0x7ffffff,因为uint8_t和int(您的常量)将具有共同的提升类型int,它不能表示大于该值的数字.将常量更改为[value]u: godbolt -
系数总和不是0xffffff或0x1000000,而是0xfff970。是有意的吗?
-
检查你的系数:
g|=*buffer >> 3?
标签: c++ gcc arm stm32 compiler-optimization