为什么 2 个未初始化的 std::set::iterator 相等?

How come 2 uninitialized std::set::iterator are equal?

std::set<>::iterator未初始化时,等于集合中的任何其他迭代器,但等于其他未初始化的迭代器。

这是特定于 GCC 的实现吗? (未初始化的迭代器是否实际初始化为无效值?)

#include <stdio.h>
#include <iostream>
#include <set>
#include <vector>

int main()
{
    std::set<int> s;
    std::set<int>::reverse_iterator inv = s.rend();
    std::cout << (inv == s.rend()) << "\n";
    std::cout << (inv == s.rbegin()) << "\n";
    s.insert(5);
    std::cout << (inv == s.rend()) << "\n";
    std::cout << (inv == s.rbegin()) << "\n";
    // invalidate
    inv = std::set<int>::reverse_iterator();
    std::cout << (inv == s.rend()) << "\n";
    std::cout << (inv == s.rbegin()) << "\n";

    auto inv2 = std::set<int>::reverse_iterator();
    std::cout << (inv == inv2) << "!!!\n";

    return 0;
}

打印:

1
1
0
1
0
0
1!!!

实例:https://onlinegdb.com/r1--46u_B

How come 2 uninitialized std::set::iterator are equal?

它们不是未初始化的。它们是值初始化的。值初始化迭代器是单数的:它不指向任何容器。

读取未初始化值的行为是未定义的,但这不是您在程序中所做的。

it is not equal to any other iterator in the set

输入迭代器之间的比较仅针对相同范围的迭代器定义。单数迭代器不指向与任何非单数迭代器相同的范围,因此比较未定义。

but it is equal to other uninitialized iterators.

两个单数迭代器总是比较相等。

Is this a GCC-specific, non-portable implementation?

未定义将单数迭代器与非单数迭代器进行比较。未定义的行为通常是 "non-portable",即使在相同的编译器版本中也是如此(除非编译器指定行为,在这种情况下它不可移植到其他编译器)。

从 C++14 开始,对于所有前向迭代器,奇异迭代器通常是标准的。

the question is: Is this GCC-specific? I am NOT asking if this is UB (it is!)

UB 就是 UB。

根据定义,您看到的结果对于特定日期的特定 运行 代码可能是唯一的。

即使没有其他实现表现出这种行为,也没关系,因为你甚至不能依赖它。

更糟的是,依靠它,你正在违约,

所以:

Is this a GCC-specific, non-portable implementation?

是的。