使用MSVC 2015比较对bool和int的引用时出现警告 [英] Warning when comparing references to bool and int with MSVC 2015

查看:143
本文介绍了使用MSVC 2015比较对bool和int的引用时出现警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码在MSVC(2015 Update 3)中产生警告-带有 / W4

The following code produces a warning with MSVC (2015 Update 3) - with /W4:

const bool& a = true;
const int& b = 1;
if(a == b)

C4805:'= =':操作中'const bool'类型和'const int'类型的不安全混合

,但没有引用,它会干净地编译。 / p>

but without the references it compiles cleanly.

const bool a = true;
const int b = 1;
if(a == b)

为什么?

编辑:

仅在不使用const的情况下进行测试

just tested without const as well

bool a = true;
int b = 1;
if(a == b)

并再次出现警告...

and the warning reappeared...

编辑2:

在Debug中进行编译...我确实必须静音 C4127:条件表达式在const noref情况下是常量 ...

Compiling in Debug... I did have to silence C4127: conditional expression is constant in the const noref case though...

编辑3:

以下是3种情况下的拆卸:

here are the disassemblies for the 3 cases:

const ref

const ref

0113BA92  in          al,dx  
0113BA93  sub         esp,24h  
0113BA96  mov         eax,0CCCCCCCCh  
0113BA9B  mov         dword ptr [ebp-24h],eax  
0113BA9E  mov         dword ptr [ebp-20h],eax  
0113BAA1  mov         dword ptr [ebp-1Ch],eax  
0113BAA4  mov         dword ptr [ebp-18h],eax  
0113BAA7  mov         dword ptr [b],eax  
0113BAAA  mov         dword ptr [ebp-10h],eax  
0113BAAD  mov         dword ptr [ebp-0Ch],eax  
0113BAB0  mov         dword ptr [ebp-8],eax  
0113BAB3  mov         dword ptr [a],eax  
    const bool& a = true;
0113BAB6  mov         byte ptr [ebp-9],1  
0113BABA  lea         eax,[ebp-9]  
0113BABD  mov         dword ptr [a],eax  
    const int& b = 1;
0113BAC0  mov         dword ptr [ebp-1Ch],1  
0113BAC7  lea         ecx,[ebp-1Ch]  
0113BACA  mov         dword ptr [b],ecx  
    if(a == b)
0113BACD  mov         edx,dword ptr [a]  
0113BAD0  movzx       eax,byte ptr [edx]  
0113BAD3  mov         ecx,dword ptr [b]  
0113BAD6  cmp         eax,dword ptr [ecx]  
0113BAD8  jne         DOCTEST_ANON_FUNC_2+5Fh (0113BAEFh)  
        throw 5;
0113BADA  mov         dword ptr [ebp-24h],5  
0113BAE1  push        offset __TI1H (0117318Ch)  
0113BAE6  lea         edx,[ebp-24h]  
0113BAE9  push        edx  
0113BAEA  call        __CxxThrowException@8 (01164B04h)  

仅const

0137BA92  in          al,dx  
0137BA93  sub         esp,0Ch  
0137BA96  mov         dword ptr [ebp-0Ch],0CCCCCCCCh  
0137BA9D  mov         dword ptr [b],0CCCCCCCCh  
0137BAA4  mov         dword ptr [ebp-4],0CCCCCCCCh  
    const bool a = true;
0137BAAB  mov         byte ptr [a],1  
    const int b = 1;
0137BAAF  mov         dword ptr [b],1  
    if(a == b)
0137BAB6  mov         eax,1  
0137BABB  test        eax,eax  
0137BABD  je          DOCTEST_ANON_FUNC_2+44h (0137BAD4h)  
        throw 5;
0137BABF  mov         dword ptr [ebp-0Ch],5  
0137BAC6  push        offset __TI1H (013B318Ch)  
0137BACB  lea         ecx,[ebp-0Ch]  
0137BACE  push        ecx  
0137BACF  call        __CxxThrowException@8 (013A4B04h)  

没有常量没有引用

0012BA92  in          al,dx  
0012BA93  sub         esp,0Ch  
0012BA96  mov         dword ptr [ebp-0Ch],0CCCCCCCCh  
0012BA9D  mov         dword ptr [b],0CCCCCCCCh  
0012BAA4  mov         dword ptr [ebp-4],0CCCCCCCCh  
    bool a = true;
0012BAAB  mov         byte ptr [a],1  
    int b = 1;
0012BAAF  mov         dword ptr [b],1  
    if(a == b)
0012BAB6  movzx       eax,byte ptr [a]  
0012BABA  cmp         eax,dword ptr [b]  
0012BABD  jne         DOCTEST_ANON_FUNC_2+44h (012BAD4h)  
        throw 5;
0012BABF  mov         dword ptr [ebp-0Ch],5  
0012BAC6  push        offset __TI1H (016318Ch)  
0012BACB  lea         ecx,[ebp-0Ch]  
0012BACE  push        ecx  
0012BACF  call        __CxxThrowException@8 (0154B04h)  

因此,似乎if语句会有一个跳转在const情况下(调试配置),它没有经过优化并且没有经过警告诊断...

So it seems there is awlays a jump for the if statement so it isn't optimized and not warning-diagnosed in the const case (debug config)...

推荐答案

是针对以下代码的GCC 6.1会发生的情况:

This is what happens with GCC 6.1 for the following code:

int ref(int num) {
   const bool& a = true;
   const int& b = 1;
   return a == b;
}

int noref(int num) {
   const bool a = true;
   const int b = 1;
   return a == b;
}


int noref_noconst(int num) {
   bool a = true;
   int b = 1;
   return a == b;
}

组装输出:

ref(int):
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -36(%rbp)
        movl    $1, %eax
        movb    %al, -21(%rbp)
        leaq    -21(%rbp), %rax
        movq    %rax, -8(%rbp)
        movl    $1, %eax
        movl    %eax, -20(%rbp)
        leaq    -20(%rbp), %rax
        movq    %rax, -16(%rbp)
        movq    -8(%rbp), %rax
        movzbl  (%rax), %eax
        movzbl  %al, %edx
        movq    -16(%rbp), %rax
        movl    (%rax), %eax
        cmpl    %eax, %edx
        sete    %al
        movzbl  %al, %eax
        popq    %rbp
        ret
noref(int):
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -20(%rbp)
        movb    $1, -1(%rbp)
        movl    $1, -8(%rbp)
        movl    $1, %eax
        popq    %rbp
        ret
noref_noconst(int):
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -20(%rbp)
        movb    $1, -1(%rbp)
        movl    $1, -8(%rbp)
        movzbl  -1(%rbp), %eax
        cmpl    -8(%rbp), %eax
        sete    %al
        movzbl  %al, %eax
        popq    %rbp
        ret

关于汇编的最简单的注意事项是,在 noref 的情况下,甚至没有跳转。这只是一个简单的 return 1

The easiest thing to note here about the assembly is that in the case of noref there isn't even a jump; it's just a simple return 1.

在MSVC中可能发生了同样的事情,然后它就越过了检测范围

The same thing is probably happening in MSVC, which then slips past the detection mechanism for warnings, and you just don't get one.

编辑:

让我们看看您的程序集,尤其是 const 版本:

Let's look at your assembly, and the const only version in particular:

    if(a == b)
0137BAB6  mov         eax,1  
0137BABB  test        eax,eax  
0137BABD  je          DOCTEST_ANON_FUNC_2+44h (0137BAD4h)  

虽然 if 语句( je )是正确的在那里,我们可以看到它实际上没有比较变量-这是触发警告的精确操作。只需将1放入寄存器中,然后将寄存器与自身进行比较。

While it is true that the if statement (je) is there, we can see that it doesn't actually compare the variables--which is the precise operation that triggers the warning. It simply puts 1 in a register and then compares the register with itself.

这篇关于使用MSVC 2015比较对bool和int的引用时出现警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆