c++ - std::begin 是空的 std::valarray 未定义行为吗?
问题描述
我在玩std::valarray
UndefinedBehaviorSanitizer,并注意到std::begin
空std::valarray
会导致未定义的行为。这是代码:
#include <valarray>
int main() {
std::valarray<int> a;
std::begin(a);
}
要重现,编译代码g++ -fsanitize=undefined
并运行结果可执行文件。
这是libstdc++std::begin
的实现。
template<class _Tp>
inline _Tp*
begin(valarray<_Tp>& __va)
{ return std::__addressof(__va[0]); }
似乎_val[0]
为空 s 创建了一个空值引用,std::valarray
这会导致未定义的行为。
这是来自 libstdc++ 的错误吗?
解决方案
§26.2.1 一般容器要求 [container.requirements.general]
表 83——容器要求
a.begin()
- 没有先决条件
所以a.begin()
必须在空容器上有效。
但是在§29 Numerics library [numerics]章节的§29.7 Numeric arrays [numarray]valarray
中定义,因此它不是容器库章节的直接部分。
这std::begin(valarray)
是在§29.7.10 valarray range access [valarray.range]中定义的,这里没有提到前提条件。最相关的引语是:
§ 29.7.10 valarray 范围访问 [valarray.range]
begin
数组返回的和end
为数组返回的迭代器保证有效,直到resize(size_t, T)
为该数组调用成员函数 (29.7.2.8) 或直到该数组的生命周期结束,以先发生者为准。template <class T> unspecified 1 begin(valarray<T>& v); template <class T> unspecified 2 begin(const valarray<T>& v);
返回: 引用数组中第一个值的迭代器。
所以问题是表 83 是否适用于此。valarray
在§29.7.2 类模板 valarray [template.valarray]中有描述,标准说:
29.7.2.1 类模板 valarray 概述 [template.valarray.overview]
- 类模板 valarray 是一个一维智能数组,
在我看来,这valarray
是一个符合§26.2.1 一般容器要求的容器
在我看来std::begin
,一个空的valarray
应该是有效的。另一方面,“返回:引用数组中第一个值的迭代器”可能暗示一个前提条件,即valarray
不能为空。所以我唯一的结论是,标准在这方面应该更加明确。
推荐阅读
- java - 更新 TableColumn 单元格中的值的问题
- flutter - 如何从颤动中显示的轮播中检索图像路径
- apache-spark - Databricks 中的同一个集群有时会失败,有时会在启动时工作
- r - r'lib'中的错误安装包未指定
- python - 传递文件名时 importlib.import_module() 如何处理重复文件?
- python - 如何设置字段将由 Django 模型中的 if 语句更改?
- pimcore - PIMCore 对成员函数的调用 supportsInheritance() on null
- html - 容器/div 不对齐(html、css)
- python - 是否可以在 python 字典中按索引引用值?
- r - GGMap 显示为蓝色