gpt4 book ai didi

c++ - lambda 如何在 MSVC2017 15.9.3 with/std :c++17? 中使用静态本地错误返回值

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:29:44 25 4
gpt4 key购买 nike

下面的示例代码打印来自 lambda 函数的值,该函数简单地递增并返回静态局部计数器变量的值。

它打印0,12,3正如预期的那样,gcc 和 C++17 的 clang。但在 Visual Studio Community 2017 15.9.3 中没有 /std:c++17设置 - 它打印 0,02,3相反。

#include <iostream>

int main() {
auto f = [] {
static int i = 0;
return i++;
};
const int v1 = f(); // Expect v1 = 0
const int v2 = f(); // Expect v2 = 1

// Prints the wrong values (MSVC 15.9.3 with /std:c++17)
std::cout << v1 << "," << v2 << std::endl; // Expect "0,1", prints "0,0"

// Prints the right values (or ought to with C++17 sequencing, anyway)
std::cout << f() << "," << f() << std::endl; // Expect "2,3", prints "2,3"

return 0;
}

奇怪的输出(在 x86 调试版本中)

0,0
2,3

它看起来像一个编译器错误(因此我们提交了报告):https://developercommunity.visualstudio.com/content/problem/347419/unexpected-return-from-lambda-with-static-local-va.html

生成的程序以何种方式出错,以至于它错误地打印了0对于v1v2 , 但正确打印 2, 3在那之后?对编译器错误是什么有任何有根据的猜测吗?

作为解决方法,我改用捕获:

auto f = [i = 0]() mutable {
return i++;
};

更新 - 作为旁注,上述示例的输出在 x86 版本构建中再次不同:

0,1
3,2

MSVC 还存在另一个问题,其中 std::cout<<尽管 /std:c++17,运算符并未从左到右排序正在设置,我推测这会导致 3,2至少在这里输出。

最佳答案

MSVC 干净地编译了以下内容:

constexpr int foo() {
static int i = 0;
return i++;
}
static_assert(foo() == foo()); // oh no

符合标准。

因此,自 C++17 起,lambda 隐式为 constexpr(如果可以的话)。 MSVC 错误地认为 lambda 是 constexpr,因此将 f() 折叠成 v2 的常量(它从 v1 )。当你直接输出它时它不会这样做,因为它显然不会像 gcc 那样急切地评估 constexpr 东西(或使用我们不知道的其他一些启发式)。

关于c++ - lambda 如何在 MSVC2017 15.9.3 with/std :c++17? 中使用静态本地错误返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53660576/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com