Bug 之 隐式类型转换

来源:互联网 发布:影视合成软件nuik 编辑:程序博客网 时间:2024/04/30 12:09

Bug 之 隐式类型转换

请看
代码1(Linux GNU g++):

    int nSendRet = -1;
    size_t nDataSize = 5;
    if(nSendRet > nDataSize) //Error
    {
        printf("nSendRet > nDataSize !!!!/n");
    }

相关的生成汇编代码:
.LCFI2:
    andl    $-16, %esp
    movl    $0, %eax
    subl    %eax, %esp
    movl    $-1, -4(%ebp)
    movl    $5, -8(%ebp)
    movl    -4(%ebp), %eax
    cmpl    -8(%ebp), %eax
    jbe .L2
    subl    $12, %esp
    pushl   $.LC0
.LCFI3:
    call    printf
    addl    $16, %esp
.L2:
    movl    $0, %eax
    leave
    ret   
   
输出1:
 nSendRet > nDataSize !!!!
 
代码2:
typedef unsigned long DWORD;

int main(void)
{
    DWORD dwCurTick = 109;
    DWORD m_dwLastInMsgTick = 110;

    if(dwCurTick - m_dwLastInMsgTick > 150000)
    {
        printf("dwCurTick - m_dwLastInMsgTick > 150000, difference=%u/n", (dwCurTick - m_dwLastInMsgTick));
    }

    size_t i = 3 - 6;

    printf("i=%u, sizeof(size_t)=%d/n", i, sizeof(size_t));

}

输出2:
dwCurTick - m_dwLastInMsgTick > 150000, difference=4294967295
i=4294967293, sizeof(size_t)=4 
 
 
Why:

 C++遇到两种不同数据类型的数值进行运算时,会将某个数做适当的类型转换,然后再进行转换。转换总是朝表达能力列强的方向进行,并且转换总是逐个运算符进行的。
 
 以下是转换的两条方向线:

 char/unsigned char --> short/unsigned short --> int/unsigned int --> double --> long double

                                                   float --> double --> long double

 
 size_t是一种无符号的整型数, 在32位系统上 定义为 unsigned int(32位无符号整形)
它的意义大致是“适于计量内存中可容纳的数据项目个数的无符号整数类型”。
所以,它在数组下标和内存管理函数之类的地方广泛使用。


 在int型和size_t进行比较时, 总是先将int转化为unsigned int然后再比较, 这个过程很可能不符合我们的要求, 导致条件判断错误。
 
[Summary]
要注意编译器的关于类型转换编译警告信息。 

原创粉丝点击