从版本 11 开始,GCC 伪造“可能会在未初始化的情况下使用”警告

问题描述 投票:0回答:0

在我们的代码库中,我们的代码可归结为以下内容(尝试使用动态堆栈分配而不是堆分配):

#include <memory>
#include <alloca.h>

void f(long long const* data, size_t len);

void h(int const* data, size_t len)
{
  std::unique_ptr<char[]> heapBuff;

  auto nbytes = len * sizeof(long long);
  long long* arr;                                                 
  if (nbytes <= 1024) {                          
    arr = reinterpret_cast<long long*>(alloca(nbytes));
  }
  else {
    heapBuff.reset(new char[nbytes]);
    arr = reinterpret_cast<long long*>(heapBuff.get());
  }

  for (size_t i=0; i < len; ++i)
    arr[i]=data[i];

  f(arr, len);
}

编译器资源管理器中的完整示例),从版本 11 开始,编译结果会在 GCC 中出现 “可能未初始化使用” 警告。

/app/h.cpp: In function 'void h(const int*, size_t)':
/app/h.cpp:23:4: warning: 'arr' may be used uninitialized [-Wmaybe-uninitialized]
   23 |   f(arr, len);
      |   ~^~~~~~~~~~
In file included from /app/h.cpp:2:
/app/f.hpp:4:6: note: by argument 1 of type 'const long long int*' to 'void f(const long long int*, size_t)' declared here
    4 | void f(long long const* data, size_t len);
      |      ^

Clang 或早期版本的 GCC 不会产生此警告。
在我看来,没有任何路径导致

arr
指针未初始化,并且代码非常简单,编译器应该可以毫无问题地理解它。我是不是错过了什么?
一件奇怪的事情是,用
alloca()
替换
malloc()
不会影响警告,但是用一些非内联
void* allocate(size_t)
函数替换它会删除警告。

c++ gcc gcc-warning
© www.soinside.com 2019 - 2024. All rights reserved.