【问题标题】:Why is this dangling-gsl warning invoked?为什么会调用这个 dangling-gsl 警告?
【发布时间】:2021-05-23 05:12:59
【问题描述】:

我正在使用 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 吗?

【问题讨论】:

  • GM 回答了我的问题,但只是留下一些参考来说明不指向临时人员的更广泛的观点(并且因为我不知道编辑问题的礼仪:1.GCC's warning 和 2. Core Guideline

标签: c++ pointers warnings clang-tidy cpp-core-guidelines


【解决方案1】:

考虑一下声明...

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 指向的内存超出其生命周期。

【讨论】:

  • 非常感谢您富有洞察力的回答!我确实了解bar.toStdString() 创建了一个临时变量,但我不完全理解为什么这是一个问题。这是否意味着在行尾,c_fomat 已经是一个悬空指针?我还更新了这个问题,以反映您对宏的了解可能会有所帮助的陈述。
  • 已编辑以添加一些说明。
猜你喜欢
  • 1970-01-01
  • 2012-03-28
  • 1970-01-01
  • 2020-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多