行为可能发生变化,UDT 返回调用约定发生变化

问题描述 投票:0回答:1

在下面的程序函数中

foo
返回一个结构体模板特化
A<int>
:

template<typename T> struct A {};

A<int> foo();

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

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

带有命令行标志

/Wall
的 Visual Studio 编译器在调用
foo()
的地方发出警告:

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

根据 Microsoft 文档中的 编译器警告 C4686

类模板特化在用于返回类型之前未定义。

在我的例子中,结构模板是之前定义的。之后仅定义函数本身(在现实生活中,函数是在另一个 .cpp 文件中定义的)。

即使使用

-Wall -Wextra -pedantic-errors

 标志,
GCC 和 Clang 也看不到程序中有任何不好的地方。在线演示:https://gcc.godbolt.org/z/1o9cTGn4j

代码有问题吗?可以在没有

#pragma warning(disable:4686)
的情况下以某种方式消除警告吗?

c++ visual-c++ compiler-warnings template-specialization
1个回答
0
投票

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

使用模板特化作为返回类型不需要实例化(也不应该,见下文)。但是,影响 UDT 返回调用约定的属性只有在定义返回类型之后才知道,并且模板专门化仅在实例化时定义。

要修复警告,您可以强制实例化模板专门化。

因此,解决方案是通过添加以下行来显式实例化模板化返回类型:

template A<int>;
© www.soinside.com 2019 - 2024. All rights reserved.