C语言中整数末字节对char类型转换的影响及MySQL相关Bug解析
问题解答
一、int转char时的数值变化原因
C语言中,当将int类型转换为char类型时,会发生截断+符号扩展(绝大多数编译器默认char为有符号类型):
- 截断:仅保留
int的低8位(char通常占1字节)。 - 符号扩展:若截断后的低8位最高位为1(二进制首位是1),会将其作为有符号数的符号位,扩展到整个
int的高位。
对应你的测试用例:
0x000000FF的低8位是0xFF,作为有符号char时,它是-1的补码(0xFF最高位为1),所以int2char返回的char值以%d打印时,会被符号扩展为0xFFFFFFFF,即十进制的-1。0x00FF0000的低8位是0x00,无论是否符号扩展,值都是0,因此打印结果为0。
回到MySQL的Bug:memcmp返回的非零int,如果低8位是0,截断为char后就会变成0,导致函数错误地返回“哈希相等”的信号,让错误密码通过验证。
二、MySQL自定义test()函数的修复原理
MySQL的test()是一个工具函数,核心作用是将非零值转为1,零值保持0,逻辑大致如下:
#define test(x) ((x) != 0 ? 1 : 0)
修复原理:
原本直接返回memcmp()的结果(int转char),可能出现非零int截断后变成0的异常;用test()包裹后,只要memcmp()返回非零(哈希不等),test()就返回1,这个值截断为char后仍是非零;只有当memcmp()返回0(哈希相等)时,test()才返回0。彻底避免了“哈希不等却返回0”的错误,确保函数返回值语义准确:0代表相等,非零代表不等。
内容的提问来源于stack exchange,提问作者Voltere
相关产品推荐
相关产品推荐

