tot*_*ing 5 c++ visual-c++ language-lawyer compiler-bug c++11
使用 MSVC 19.11 编译以下代码会产生输出
With 32: 0 99 2 With 64: 0 1 2使用 32 位编译器,并在
With 32: 0 1 2 With 64: 0 99 2使用 64 位编译器。
问题是单个元素初始值设定项列表的类型恰好是size_t。这是一个编译器错误(到目前为止我还没有发现它在任何地方报告过),而不是标准不明确的情况(clang 和 gcc 都没有这个问题)?
#include <cstdint>
#include <vector>
#include <iostream>
int main() {
using T = std::uint16_t;
// fixed with uint32 / uint64 on 32 / 64 bit compilers, respectively,
// but not with int32_t / int64_t
{
std::vector<T> s0;
// std::vector<T> s1{ 99u }; // OK
// std::vector<T> s1 = { 99u }; // OK
std::vector<T> s1( { 99u } ); // BUG?
// EDIT: std::vector<T> s1( {{ 99u }} ); // also OK
std::vector<T> s2( { 40u, 70u } );
std::cout << "With " << sizeof(0u)*8 << ':' << ' '
<< s0.size() << ' ' << s1.size() << ' ' << s2.size() << '\n';
}
{
std::vector<T> s0;
std::vector<T> s1( { 99ull } );
std::vector<T> s2( { 40ull, 70ull } );
std::cout << "With " << sizeof(0ull)*8 << ':' << ' '
<< s0.size() << ' ' << s1.size() << ' ' << s2.size() << '\n';
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
命令和编译器:
cl.exe ilist.cpp & .\ilist.exe # no extra cl arguments
cl.exe
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25507.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved. (or x86)
x64\cl.exe and x86\cl.exe from
...\Tools\MSVC\14.11.25503\bin\HostX64\
Run Code Online (Sandbox Code Playgroud)
是的,这是 Visual Studio 编译器错误。
\n一个更简单的例子来说明问题:
\n#include <initializer_list>\n#include <cstddef>\n\nstruct V {\n size_t sz;\n constexpr V(size_t s) { sz = s; } \n constexpr V(std::initializer_list<int> l) { sz = l.size(); }\n};\n\nstatic_assert( V({size_t(3)}).sz == 1 );\nRun Code Online (Sandbox Code Playgroud)\n这里struct V模仿了std::vector它的两个构造函数。
\n\n列表初始化序列 L1 是比列表初始化序列 L2 更好的转换序列,如果\n(3.1.1)\nL1 对于某些 X 转换为 std\xe2\x80\x8b::\xe2\x80\x8binitializer_\xc2\xadlist而L2不...
\n
所以在这个例子中V({size_t(3)})应该调用构造函数V(std::initializer_list<int> l),它在GCC和Clang中这样做,但在MSVC中则不然。演示: https: //gcc.godbolt.org/z/3q64f7Yr7
此 MSVC 错误已在 Visual Studio 2022 版本 17.9 中修复:https://developercommunity.visualstudio.com/t/Wrong-constructor-of-std::vector -selecte/1652923
\n