Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible compiler bug in MSVC

The following code compiles with gcc and clang (and many other C++11 compilers)

#include <stdint.h>

typedef int datatype;

template <typename T>
struct to_datatype {};

template <>
struct to_datatype<int16_t> {
  static constexpr datatype value = 1;
};

template <typename T>
class data {
 public:
  data(datatype dt = to_datatype<T>::value) {}
};

int main() {
  data<char> d{to_datatype<int16_t>::value};
}

when compile with (almost) latest MSVC

> cl .\test.cpp /std:c++latest /permissive-
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
.\test.cpp(16): error C2039: 'value': is not a member of 'to_datatype<T>'
        with
        [
            T=char
        ]
.\test.cpp(16): note: see declaration of 'to_datatype<T>'
        with
        [
            T=char
        ]
.\test.cpp(20): note: see reference to class template instantiation 'data<char>' being compiled

Is this a bug of MSVC? If yes, which term in C++ standard best describe it?

If you replace part of the code with

template <typename T>
class data {
 public:
  data(datatype dt) {}
  data() : data(to_datatype<T>::value) {}
};

it compiles smoothly anyway.

like image 719
Cloud Avatar asked Dec 31 '19 17:12

Cloud


People also ask

What compiler does MSVC use?

Microsoft C++ Compiler (MSVC) This is the default compiler for most Visual Studio C++ projects and is recommended if you are targeting Windows.

Is MinGW better than MSVC?

The DLL sizes are comparable, if optimization is set to "-O2" for MinGW-w64, with "-O3" the DLLs from MinGW-w64 are larger. Binary files compiled with MinGW-w64 are performing significantly better than those compiled with MSVC.

Does MSVC support C ++ 17?

The /std:c++17 option enables C++17 standard-specific features and behavior. It enables the full set of C++17 features implemented by the MSVC compiler.

Can MSVC compile C?

By default, the MSVC compiler treats all files that end in . c as C source code, and all files that end in . cpp as C++ source code. To force the compiler to treat all files as C no matter the file name extension, use the /TC compiler option.


1 Answers

I would say MSVC is wrong not to accept the code.

According to [dcl.fct.default]/5 of the C++17 standard final draft, name lookup in default arguments of a member function of a class template is done according to the rules in [temp.inst].

According to [temp.inst]/2 implicit instantiation of a class template does not cause instantiation of default arguments of member functions and according to [temp.inst]/4 a default argument for a member function of a (non-explicit specialization of a) class template is instantiated when it is used by a call.

There is no call using the default argument to_datatype<T>::value in your code and so it should not be instantiated. Therefore there shouldn't be an error about lookup of value in to_datatype<char> failing.

(The relevant sections in the C++11 standard final draft have equivalent wording, except for numbering, see [decl.fct.default]/5, [temp.inst]/1 and [temp.inst]/3 instead.)

like image 79
walnut Avatar answered Nov 15 '22 21:11

walnut