Jac*_*son 7 c++ windows winapi visual-c++
我得到了一些格式不正确的代码,如下所示,但它是使用 MSVC 19.32.31329 和 /std:c++latest 构建的。
#include <Windows.h>
template<typename T>
void foo() {
int i;
// Can be anything that looks like a function call
baz(i.str());
}
int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
int i;
// The following line is wrong because i has an integral type
// and doesn't have .str().
i.str();
}
Run Code Online (Sandbox Code Playgroud)
该代码显然是错误的,不应该编译,但它确实可以编译。这是编译器错误吗?
是的,这是一个编译器错误,显然是在 19.32 版本中引入的。/std:c++latest使用或进行编译时可以观察到这一点/std:c++20。
看来函数模板内的任何内容都可以诱骗 MSVC 学习有关整数类型的新规则。正如问题中所示,一旦编译器完成解析,foo它随后将允许任何exp整数类型的表达式调用任何(幻想)成员(例如str())(使用整数、浮点值、布尔值、指针和数组进行验证)。
在对该问题的评论中提出了一个相关问题。
当函数模板在这里foo 被实例化时,MSVC将编译以下代码:
extern void bar(int);
template<typename T>
void foo()
{
int i;
// This should not compile
bar(i.str());
}
int WinMain(void*, void*, char*, int)
{
foo<int>();
}
Run Code Online (Sandbox Code Playgroud)
尽管这可能遵循法律条文中的规则[temp.res.general/6.4] :
如果出现以下情况,则程序格式错误,无需诊断:
- ...
- 由于不依赖于模板参数的构造,紧随其定义之后的模板的假设实例化将是格式错误的,或者
确实,改成int i无法auto i = sizeof(T) 编译。这可能是无关的。
错误报告已发布(请参阅此答案)。
这是一个 msvc 错误。该程序格式错误,无需诊断。这可以从temp#res.general6.1中看出,其中指出:
- 可以在任何实例化之前检查模板的有效性。
如果出现以下情况,则程序格式错误,无需诊断:
- 6.1) 无法为模板或模板内 constexpr if 语句的子语句生成有效的特化,并且模板未实例化,或者
此外,temp#res.general6.4也适用于此处:
由于不依赖于模板参数的构造,紧随其定义之后的模板的假设实例化将是格式错误的,或者
(强调我的)
相同的错误报告已提交为:
someint.str()当存在无效的函数模板时,调用将编译