Mat*_*lia 58 c++ pointers comparison-operators language-lawyer c++11
在检查另一个问题的引用时,我注意到C++ 11中的一个奇数子句,在[expr.rel]3:
指针
void(后指针转化)可以进行比较,以确定其结果如下:如果两个指针表示相同的地址或均为空指针值,其结果是true,如果操作者<=或>=与false其他方式; 否则结果未指定.
这似乎意味着,一旦两个指针被投入void *,它们的排序关系就不再有保证; 例如,这个:
int foo[] = {1, 2, 3, 4, 5};
void *a = &foo[0];
void *b = &foo[1];
std::cout<<(a < b);
Run Code Online (Sandbox Code Playgroud)
似乎没有具体说明.
有趣的是,这个子句在C++ 03中不存在并且在C++ 14中消失了,所以如果我们采用上面的例子并应用C++ 14的措辞,我会说3.1
- 如果两个指针指向同一数组的不同元素或其子对象,则指向具有较高下标的元素的指针比较大.
将应用,作为a并b指向同一数组的元素,即使它们已被转换为void *.请注意,3.1的措辞在C++ 11中几乎完全相同,但似乎被该void *子句覆盖了.
我的理解是对的吗?在C++ 11中添加并立即删除的奇怪子句有什么意义?或者它可能仍然存在,但是被标准的其他部分移动/隐含?
P.W*_*P.W 36
TL; DR:
void指针指定关系运算符(核心问题879,见本文末尾);void指针的奇怪条款是在C++ 11中添加来解决它的,但这又引发了另外两个核心问题583和1512(见下文);void *比较.核心问题583:关系指针与空指针常量的比较
- 与空指针常量的关系指针比较Section:8.9 [expr.rel]
在C中,这是不正确的(参见C99 6.5.8):
Run Code Online (Sandbox Code Playgroud)void f(char* s) { if (s < 0) { } } ...but in C++, it's not. Why? Who would ever need to write (s > 0) when they could just as well write (s != 0)?这是自ARM以来的语言(可能更早); 显然这是因为只要其中一个操作数是指针类型,就需要在两个操作数上执行指针转换(7.11 [conv.ptr]).因此看起来"null-ptr-to-real-pointer-type"转换正在与其他指针转换搭便车.
拟议决议(2013年4月):
问题1512的决议解决了这个问题.
核心问题1512:指针比较与资格转换
- 指针比较与资格转换部分:8.9 [expr.rel]
根据8.9 [expr.rel]第2段,描述指针比较,
指针操作数(或指针操作数和空指针常量,或两个空指针常量,至少其中一个)执行指针转换(7.11 [conv.ptr])和限定转换(7.5 [conv.qual])是非整数的)将它们带到它们的复合指针类型.这似乎使以下示例格式错误,
Run Code Online (Sandbox Code Playgroud)bool foo(int** x, const int** y) { return x < y; // valid ? } because int** cannot be converted to const int**, according to the rules of 7.5 [conv.qual] paragraph 4.对于指针比较来说这似乎太严格了,当前的实现接受了这个例子.
拟议决议(2012年11月):
解决上述问题的相关摘录见文章:指针比较与资格转换(修订版3).
以下还解决了核心问题583.
5.9 expr.rel第1至5段的变化:
在本节中,以下语句(C++ 11中的奇数子句)已被删除:
指针
void(后指针转化)可以进行比较,以确定其结果如下:如果两个指针表示相同的地址或均为空指针值,其结果是true,如果操作者<=或>=与false其他方式; 否则结果未指定
并添加了以下声明:
- 如果两个指针指向同一数组的不同元素或其子对象,则指向具有较高下标的元素的指针比较大.
- 如果一个指针指向一个数组的元素或指向其子对象,而另一个指针指向一个超过该数组的最后一个元素的指针,则后一指针比较大.
因此,在C++ 14(n4140)部分[expr.rel]/3 的最终工作草案中,上述陈述是在解决时陈述的.
挖掘为什么添加这个奇数子句的原因让我得到了更早的问题879:缺少指针类型的内置比较运算符.该问题的拟议决议(2009年7月)导致增加了该条款,该条款于2009年10月被投票通过WP.
这就是它被包含在C++ 11标准中的方式.
| 归档时间: |
|
| 查看次数: |
2978 次 |
| 最近记录: |