首页 > 解决方案 > 为什么会调用这个 dangling-gsl 警告?

问题描述

我正在使用 clang-tidy 分析代码库,并看到一个我不理解的警告。警告由以下代码行调用:

void fun(const QString& bar) {
    const char* c_format = bar.toStdString().c_str();
    expand_some_macro(c_format);
}

c_format在扩展宏中传递,其内容如下:

#define expand_some_macro(c_format)\
    char buffer[MAX_SIZE];\
    va_list args;\
    va_start(args, c_format);\
    vsnprintf(buffer, MAX_SIZE, _TRUNCATE, c_format, args);\
    va_end(args);

shlobj其中包括我目前不理解的来自标头的函数调用。生成以下clang-tidy警告:

warning: object backing the pointer will be destroyed at the end of the full-expression [clang-diagnostic-dangling-gsl]

我浏览了网络,尤其是c++ core Guidelines,试图让自己了解这个警告,但找不到合适的参考。这让我想到了两组问题:

  1. 此警告的参考是什么?我在哪里可以了解这个类似的警告?
  2. 上面的代码可能有什么问题?我需要delete[] c_format在范围结束时调用吗?

标签: c++pointerswarningsclang-tidycpp-core-guidelines

解决方案


考虑一下声明...

const char* c_format = bar.toStdString().c_str();

bar.toStdString()返回一个临时的std::string,它将在下一条语句之前被销毁。但是您随后调用std::string::c_str()该临时变量并保存其返回值以用于...

expand_some_macro(c_format);

因此,到上面的表达式中使用时间时,它指向的内存在临时被销毁c_format时已经被释放。std::string因此发出警告。

然而,如果不知道你的宏做了什么(或者为什么它需要是一个宏),很难说更多。

编辑:

澄清一下,您当前拥有的代码可以(或多或少)重写为...

const char* c_format = nullptr;
{
    std::string str = bar.toStdString();
    c_format = str.c_str();
}
expand_some_macro(c_format);

因此,您正在使用c_format超出其生命周期的内存。


推荐阅读