使用MSVC 2015比较对bool和int的引用时出现警告 [英] Warning when comparing references to bool and int with MSVC 2015
问题描述
以下代码在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屋!