关于std::array<T,0>引发GCC不同编译行为的技术咨询
GCC中std::array空容器下标访问的未定义行为判定疑问
- 以下代码在GCC中编译后仅生成RET指令:
void f( ) { std::array<int, 0> a; std::array<int, 1> b; std::copy_n(a.begin( ), 0, b.begin( )); }
- 但下面这段代码从GCC 13版本开始,编译后会生成UD2指令,编译器判定其触发了未定义行为:
void f( ) { std::array<int, 0> a; std::array<int, 1> b; std::copy_n(&a[0], 0, &b[0]); }
两者的核心差异在于对空std::array的访问方式:
- 第一段代码使用
a.begin()作为std::copy_n的源起始迭代器,空std::array的begin()是合法迭代器(与end()相等),且std::copy_n在计数为0时不会解引用迭代器,因此行为完全合规。 - 第二段代码调用了
std::array<int, 0>::operator[],根据C++标准,空std::array没有元素,operator[]的返回值无合法对象依托,哪怕只是取其地址、不访问内存,这一操作本身就属于未定义行为。
GCC 13开始对这类未定义行为做了更严格的编译期检查,生成UD2指令触发陷阱是编译器遵循标准、主动诊断UB的表现,并非GCC的bug。
内容的提问来源于stack exchange,提问作者Rodrigo Castro
相关产品推荐
相关产品推荐

