Given the following C++ code:
#include <stdio.h>
static constexpr int x = 1;
void testfn() {
if (x == 2)
printf("This is test.\n");
}
int main() {
for (int a = 0; a < 10; a++)
testfn();
return 0;
}
Visual Studio 2019 produces the following Debug build assembly (viewed using Approach 1 of accepted answer at: How to view the assembly behind the code using Visual C++? )
int main() {
00EC1870 push ebp
00EC1871 mov ebp,esp
00EC1873 sub esp,0CCh
00EC1879 push ebx
00EC187A push esi
00EC187B push edi
00EC187C lea edi,[ebp-0CCh]
00EC1882 mov ecx,33h
00EC1887 mov eax,0CCCCCCCCh
00EC188C rep stos dword ptr es:[edi]
00EC188E mov ecx,offset _6D4A0457_how_compiler_treats_staticconstexpr@cpp (0ECC003h)
00EC1893 call @__CheckForDebuggerJustMyCode@4 (0EC120Dh)
for (int a = 0; a < 10; a++)
00EC1898 mov dword ptr [ebp-8],0
00EC189F jmp main+3Ah (0EC18AAh)
00EC18A1 mov eax,dword ptr [ebp-8]
00EC18A4 add eax,1
00EC18A7 mov dword ptr [ebp-8],eax
00EC18AA cmp dword ptr [ebp-8],0Ah
00EC18AE jge main+47h (0EC18B7h)
testfn();
00EC18B0 call testfn (0EC135Ch)
00EC18B5 jmp main+31h (0EC18A1h)
return 0;
00EC18B7 xor eax,eax
}
As can be seen in the assembly, possibly because this is a Debug build, there is pointless references to the for
loop and testfn
in main
. I would have hoped that they should not find any mention in the assembly code at all given that the printf
in testfn
will never be hit since static constexpr int x=1
.
I have 2 questions:
(1)Perhaps in the Release build, the for
loop is optimized away. How can I check this? Viewing the release build assembly code does not work for me even on using the Approach 2 specified at at: How to view the assembly behind the code using Visual C++? . The file with the assembly code is not produced at all.
(2)In using static constexpr int/double/char
as opposed to #define
's, under what circumstances is one guaranteed that the former does not involve any unnecessary overhead (runtime computations/evaluations)? #define
's, though much maligned, seem to offer much greater guarantee than static constexpr
's in this regard.
The issue here is that you are compiling the code using a debug build. If you want sanity in the asm, compile as release instead. The problem is that a debugger is used to help confirm the logic of the underlying code. The logic in your underlying code is that it should call testfn() 10 times. As a result, you should be able to place a breakpoint on that method, and hit it at the correct point in the execution. In a release build, that breakpoint would never be hit (because it would have been optimised away).
In your case however, it's entirely incorrect to say that the constexpr is being ignored. You may notice that there are no calls to printf() in the generated asm, so the compiler has correctly identified that if (x == 2) can never be true, and has removed it. However, if the compiler removed the call to testfn() completely, your breakpoint would never be hit, and the debugger would basically be useless.
Don't look at the output of a debug build and imagine it tells you anything useful about the code or compiler. You should expect the code to be deliberately de-optimised.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.