鉴于p是一个指针是" p> nullptr"良好形成的呢?

时间:2014-10-27 14:50:23

标签: c++ pointers c++11 language-lawyer c++14

给出指针p

char *p ; // Could be any type
假设p已正确初始化,

以下格式良好:

if (p > 0) // or p > nullptr

更一般地说,当一个操作数是指针而另一个是空指针常量时,使用关系运算符是否良好?

1 个答案:

答案 0 :(得分:27)

在C ++ 14中,这段代码格式不正确,但在C ++ 14之前,这是格式良好的代码(但结果未指定),如defect report 583: Relational pointer comparisons against the null pointer constant所述:

  

在C中,这是不正确的(参见C99 6.5.8):

void f(char* s) {
    if (s < 0) { }
}
     

...但在C ++中,它不是。为什么?谁需要写(s> 0)   什么时候他们也可以写(s!= 0)?

     

这一直是自ARM以来的语言(可能更早);   显然它是因为指针转换(4.10 [conv.ptr])需要   只要其中一个操作数是,就在两个操作数上执行   指针类型。所以它看起来像&#34; null-ptr-to-real-pointer-type&#34;   转换正在与其他指针转换搭便车。

在C ++ 14中,当N3624applied to the draft C++14 standard N3478时,这是583的修订版。建议的1512注意事项:

  

第1512期的决议解决了这个问题。

并且问题N3478建议的解决方案是5.9 N3624是N3478的修订版):

  

拟议的措辞见N3478号文件。

第5.9节从C ++ 11更改为C ++ 14

部分1 关系运算符C++11 draft standardC++14 draft standard之间发生了很大变化,以下重点介绍了最相关的差异(强调我的进展转发),来自0段:

  

操作数应具有算术,枚举或指针类型,或   输入std :: nullptr_t

更改为:

  

操作数应具有算术,枚举或指针类型

因此类型std::nullptr_t不再是有效的操作数,但仍然留下4.10这是空指针常量,因此可以转换( section { {1}} )到指针类型

这由第2段涵盖,在C ++ 11中说:

  

[...] 指针转换(4.10)和资格转换(4.4)   在指针操作数(或指针操作数和空值上)执行   指针常量,或两个空指针常量,至少有一个   这是非整数)将它们带到复合指针类型。   如果一个操作数是空指针常量,则为复合指针类型   如果另一个操作数也是空指针常量,则为std :: nullptr_t   或者,如果另一个操作数是指针,则另一个操作数的类型   操作数。[...]

这明确地为空指针常量操作数提供了一个例外,在C ++ 14中更改为以下内容:

  

通常的算术转换是在操作数上执行的   算术或枚举类型。 如果两个操作数都是指针,则指针   执行转换(4.10)和资格转换(4.4)   将它们带到复合指针类型(第5条)。的后   转换时,操作数应具有相同的类型。

其中没有允许0转换为指针类型的情况。两个操作数必须是指针才能应用指针转换,并且要求转换后操作数具有相同的类型。在一个操作数是指针类型而另一个是空指针常量 0的情况下不满足。

如果两个操作数都是指针但是一个是空指针值怎么办?

R Sahu问,下面的代码是否格式正确?:

char* p = "";
char* q = nullptr;
if ( p > q ) {}

是的,在C ++ 14中,此代码格式正确,pq都是指针,但未指定比较结果。两个指针的定义比较在第3段中列出,并说:

  

比较指向对象的指针定义如下:

     
      
  • 如果两个指针指向同一个数组或其子对象的不同元素,则指向具有更高元素的元素   下标比较大。

  •   
  • 如果一个指针指向一个数组的元素,或指向一个子对象,另一个指针指向一个指针的最后一个元素。   数组,后一个指针比较大。

  •   
  • 如果两个指针指向同一个对象的不同非静态数据成员,或者指向这些成员的子对象,则递归地,   指向后来声明的成员的指针比较大,提供了两个   成员具有相同的访问控制(第11条)并提供了他们的   上课不是工会。

  •   

此处未定义空指针值,稍后在段落4中定义:

  

[...]否则,未指定每个运算符的结果。

在C ++ 11中,它专门在第3段中未指明结果:

  

如果同一类型的两个指针p和q指向不同的对象   不是同一对象的成员或同一数组的元素   或者对于不同的函数,或者如果只有其中一个为null,则为结果   p q,p <= q,p> = q未指定。