c++visual-c++compiler-warningstemplate-specialization

Possible change in behavior, change in UDT return calling convention


In the following program function foo returns a struct template specialization A<int>:

template<typename T> struct A {};

A<int> foo();

int main() {
    foo(); //MSVC warning here
}

A<int> foo() { return {}; }

Visual Studio compiler with the command line flag /Wall issues the warning in the place where foo() is called:

warning C4686: 'foo': possible change in behavior, change in UDT return calling convention

According to Microsoft documentation on Compiler Warning C4686

A class template specialization wasn't defined before it was used in a return type.

In my case, struct template is defined before. Only the function itself is defined after (in real life the function is defined in another .cpp file).

GCC and Clang do not see anything bad in the program even with -Wall -Wextra -pedantic-errors flags. Online demo: https://gcc.godbolt.org/z/1o9cTGn4j

Is there anything wrong with the code? Can the warning be silenced somehow without #pragma warning(disable:4686)?


Solution

  • Per https://developercommunity.visualstudio.com/t/msvc-fails-to-instantiate-stdarray-and-erroneously/1150191

    Using a template specialization as a return type doesn't require its instantiation (and shouldn't, see below). However, the property which impacts the UDT return calling convention is only known after the return type is defined and a template specialization is only defined when it is instantiated.

    To fix the warning, you can force the instantiation of the template specialization.

    So the solution is to explicitly instantiate the templated return type by adding the following line:

    template A<int>;