Weird behaviour with 'if constexpr' and templates in MSVC
Asked Answered
O

1

8

The code below behaves incorrectly.

When f<0> or f<5> is called, it prints as if k = true, but the if statement behaves as if k = false. When f<1> is called, it does the opposite.

The bug does not appear without templates, constexpr, or the negator(!). It can be removed by having a separate variable (see below). I'm assuming this has something to do with how MSVC deals with templates?

#include <stdio.h>

const bool k = false;

template<int n>
void f()
{
    printf("%d %d\n", k, n); //prints 1 0 or 1 5 when calling f<0> or f<5>, respectively
    //kop = !k 
    if constexpr(!k)//if constexpr(kop) works fine
    {
        //doesn't enter the conditional when calling f<1>
        int f = 9;
        printf("%d %d\n", f, n); 
    }
}

int main()
{
    f<0>();
    f<1>();
    f<1>();
    f<5>();
}
Oxidate answered 18/7 at 21:12 Comment(8)
Congratulations, looks like you found a bug with MSVC. What version of MSVC are you using? What command line flags are you using? What platform are you targeting? I recommend filing a compiler bug with Microsoft.Platonic
@danielcreatd Verified. Odd MSVC bug. The workaround is to make k constexpr.Towery
@Platonic This bug works in C++ 14, 17, and 20 on MSVC, and optimisation flags don't seem to change anything either.Oxidate
Good to know. Please file a bug with Microsoft. There is nothing we can do about the bug here, except to figure out workarounds to avoid the bug. (Which you've already appear to have figured out.)Platonic
@Platonic I did file a report, although it may be a duplicate since it's a relatively common situation (but I couldn't find one myself) or flagged as not important since it has a simple workaround.Oxidate
Thank you! I assure you that all bugs are triaged, processed, logged, and prioritized. The bona fide compiler bugs usually get high priority. (I haven't worked at Microsoft since 2014, when I worked on VS as a dev. I presume the process is the same today as it was then, because the process works well.)Platonic
@Platonic Note that the wrong output is only observed with /permissive- flag as noticed in my answer. See demoMadelon
Note also that msvc in c++20 uses /permissive- by default. So even if you don't explicitly use /permissive- with c++20, wrong output will be printed. With c++17, you would have to specify the flag explicitly that it produces the wrong output as noticed in my previous comment.Madelon
M
4

This is a confirmed msvc bug that has been fixed.

Note that the wrong output is only observed with /permissive- flag. See demo

Here is the confirmed bug link:

MSVC generates wrong output with permissive- flag

Madelon answered 19/7 at 5:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.