You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

g++编译时[-Wdangling-reference]警告是否为误报?

GCC 13.x中-Wextra触发的范围视图悬垂引用警告是误报吗?

以下是测试代码:

#include <iostream>
#include <vector>
#include <ranges>

int main()
{
  std::vector<int> a{ 1, 2, 3, 4, 5 };
  
  std::span<const int> b{ a };

  for ( auto i : b | std::views::drop(1) )
    std::cout << i << '\n';
}

使用-Wextra选项编译上述代码时,GCC 13.1或13.2会发出如下警告:

<source>: In function 'int main()':
<source>:11:40: warning: possibly dangling reference to a temporary [-Wdangling-reference]
   11 |   for ( auto i : b | std::views::drop(1) )
      |                                        ^
<source>:11:40: note: the temporary was destroyed at the end of the full expression 'std::ranges::views::__adaptor::operator|<_Partial<std::ranges::views::_Drop, int>, std::span<const int>&>(b, ((const std::ranges::views::__adaptor::_RangeAdaptor<std::ranges::views::_Drop>*)(& std::ranges::views::drop))->std::ranges::views::__adaptor::_RangeAdaptor<std::ranges::views::_Drop>::operator()<int>(1))'

其他编译器及旧版本GCC均无此提示,请问这属于误报还是遗漏了什么细节?


回答

这是GCC 13.x版本的误报,核心原因如下:

  • std::views::drop作为范围适配器,返回的视图对象仅持有对原始std::span的引用,而span引用的vector a在main函数栈上,生命周期完全覆盖整个for循环,不存在悬垂风险。
  • 对于基于范围的for循环,标准要求循环会将范围表达式的结果绑定到一个隐式的引用变量上,该变量的生命周期会持续到循环结束。也就是说,b | std::views::drop(1)产生的临时视图对象不会在完整表达式结束时销毁,而是会存活到循环执行完毕,所以不会出现引用悬垂的问题。

这个问题属于GCC在范围视图警告逻辑上的实现缺陷,后续的GCC 14版本已经修复了该误报。

内容的提问来源于stack exchange,提问作者Bob__

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:22:35