I was bitten by the inadvertent matching of C ++ functions using MSVC. I can reduce it to the following test case:
#include <iostream> enum Code { aaa, bbb }; struct MyVal { Code c; MyVal(Code c): c(c) { } }; void test(int i, MyVal val) { std::cout << "case " << i << ": value " << val.c << std::endl; } void test(int i, double* f) { std::cout << "case " << i << ": WRONG" << std::endl; } const Code v1 = aaa; Code v2 = aaa; const Code v3 = bbb; int main() { const Code w1 = aaa; Code w2 = aaa; const Code w3 = bbb; test(1, v1); // unexpected MSVC WRONG test(2, v2); test(3, v3); test(4, aaa); test(5, w1); // unexpected MSVC WRONG test(6, w2); test(7, w3); return 0; }
I expected that all 7 test calls would correspond to the first overload, and GCC ( live example ) and Clang ( live example ) correspond to this, as expected:
case 1: value 0 case 2: value 0 case 3: value 1 case 4: value 0 case 5: value 0 case 6: value 0 case 7: value 1
But the MSVC ( live example ) matches cases 1 and 5 for the βwrongβ overload (I found this behavior in MSVC 2013 and 2015):
case 1: WRONG case 2: value 0 case 3: value 1 case 4: value 0 case 5: WRONG case 6: value 0 case 7: value 1
It seems that pointer conversion is preferable to MSVC for the const enum variable with a (random) value of 0. I would expect this behavior with a literal of 0, but not with an enumeration variable.
My questions: Is MSVC behavior standard? (Perhaps for an older version of C ++?) If not, is this a known extension or bug?
source share