为什么 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!!!
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?
是的。
当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!!!
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?
是的。