clang-tidy 的 bugprone-exception-escape 在 MSVC STL 中表现得很奇怪

Ray*_*ght 6 c++ visual-c++ clang-tidy

我在一个项目中使用 clang-tidy 10,它在带有 MSVC STL 的 Windows 上表现得很奇怪。一个最小的例子如下:

#include <iostream>
#include <stdexcept>

int main()
{
    try {
        throw std::runtime_error {"Boom!"};
    } catch (...) {
        std::cerr << "Unexpected non-exception error!\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我告诉它包含检查 bugprone-exception-escape,它会告诉我函数“main”中可能会引发异常。但是,如果我使用以下命令将行流更改为 std::cerr ,则检查不会引起投诉:

std::cerr << "Unexpected non-exception error!\n" << std::flush;
Run Code Online (Sandbox Code Playgroud)

我假设一个语句中的两个连续流操作是导致不同行为的原因,因为以下确实会引发问题。

std::cerr << "Unexpected non-exception error!\n";
std::cerr << std::flush;
Run Code Online (Sandbox Code Playgroud)

我注意到 clang-tidy 不会抱怨 Linux 上的任何这些示例,至少如果我传递 -stdlib=libc++ 的话。我是否遗漏了一些奇怪的微妙之处,或者这是 clang-tidy 和/或 MSVC 的 STL 实现中的错误?

Dan*_*osh 2

我不能肯定地说,但这似乎很可能是一个错误。已经提出了两个类似的错误报告/问题:https://github.com/llvm/llvm-project/issues/54668https://github.com/llvm/llvm-project/issues/56411。第一个已经创建了一个补丁来修复它(在撰写本文时,它仍在审查中)。

我的猜测是,通过管道将单个字符串文字传递给 cerr 会以某种方式导致字符串移动,从而触发我链接的第一个问题中报告的错误。可能存在某种优化,它试图将字符串直接移动到缓冲区中,并使用返回的 ostream 执行另一个操作以某种方式阻止该优化。

或者,这是导致琴弦移动问题的根本问题的另一种情况。即,函数中存在多次深度调用的抛出,但其中一个调用被声明为 noexcept,因此诊断不应进一步向上传播。