为什么clang ++会报告一个结构化绑定,其中"在初始化期间存储到'...'的值永远不会被读取"?

agh*_*ast 5 c++ clang++ c++17 structured-bindings

我有以下测试用例:

testcase("[room] exits") {
    auto [center, east, north, south, west] = make_test_rooms();

    check_eq(center->east(), east);
    check_eq(center->north(), north);
    check_eq(center->south(), south);
    check_eq(center->west(), west + 1);
}
Run Code Online (Sandbox Code Playgroud)

当我编译它时,clang ++(clang版本5.0.1(标签/ RELEASE_501/final))报告:

room.cpp:52:7: note: Value stored to '[center, east, north, south, west]' during its initialization is never read
Run Code Online (Sandbox Code Playgroud)

在上面的代码,testcase和check_eq用于定义的宏的文档测试单元测试包展开后DOCTEST_TEST_CASE()(某种自注册变量+函数对)和DOCTEST_CHECK_EQ(基本上,"断言== B"魔术带处理).

我知道这段代码正在执行,因为这west + 1是故意引入的错误.当我运行我的测试时,我得到一个像这样的失败消息:

===============================================================================
/.../room.cpp(51)
TEST CASE:  [room] exits

/.../room.cpp(57) ERROR!
  CHECK_EQ( center->west(), west + 1 )
with expansion:
  CHECK_EQ( 0x00007fd6f1d011a0, 0x00007fd6f1d011f8 )
Run Code Online (Sandbox Code Playgroud)

据我所见,我使用结构化绑定中的所有值:center出现在我的检查的左侧,并north, south, east, west显示在右侧.为什么clang ++会报告"永不读"的内容?

更新

这是重现问题的代码.我运行此命令行(取自输出make VERBOSE=1和减少):

$ /opt/local/bin/cmake -E __run_co_compile --tidy=/opt/local/bin/clang-tidy --source=test.cpp -- /opt/local/bin/clang++  -g -std=gnu++1z -o test.cpp.o -c test.cpp
/Users/austin/Code/agb/test.cpp:12:7: warning: Value stored to '[a, b, c]' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
        auto [a,b,c] = foo();
             ^
/Users/austin/Code/agb/test.cpp:12:7: note: Value stored to '[a, b, c]' during its initialization is never read
Run Code Online (Sandbox Code Playgroud)

我使用这个源文件test.cpp:

#include <tuple>

static std::tuple<int, int, int>
foo()
{
    return {1,2,3};
}

bool
test()
{
    auto [a,b,c] = foo();

    return a<b and b<c;
}
Run Code Online (Sandbox Code Playgroud)

小智 -2

在clang 分析器常见问题解答中,这被认为是常见的误报:

问:如何告诉静态分析器我不关心特定的死存储?

当分析器发现存储在变量中的值从未被使用时,它将生成类似于以下消息的消息:

Value stored to 'x' is never read
Run Code Online (Sandbox Code Playgroud)

您可以使用 (void)x; 习惯用法是承认代码中存在死存储,但您不希望将来报告它。

推理为什么是误报是没有用的。随着代码的细微变化或 Clang 版本之间的细微变化,警告可能会消失/重新出现。

  • 问题中的死店在哪里? (2认同)