给定int ** p1和const int ** p2,p1 == p2格式正确吗? [英] Given int **p1 and const int**p2 is p1 == p2 well formed?

查看:109
本文介绍了给定int ** p1和const int ** p2,p1 == p2格式正确吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

提供以下功能:

void g(int **p1, const int**p2)
{
   if (p1 == p2) { }  
}

clang(回到3.0版)会产生此警告( 实时查看 ):

clang(back to version 3.0) produces this warning (see it live):

warning: comparison of distinct pointer types ('int **' and 'const int **')
uses non-standard composite pointer type 'const int *const *' 
[-Wcompare-distinct-pointer-types]
  if (p1 == p2) { }
      ~~ ^ ~~

使用-pedantic-errors标志会将其变为错误.根据标准,gcc(回到4.3.6 )和Visual Studio( 2013 )都不会发出警告,只是比较:

Using -pedantic-errors flags turns it into an error. Neither gcc(back to 4.3.6) nor Visual Studio(2013) produce a warning, according to the standard, is the comparison:

p1 == p2

组织良好?

更笼统地说,如果两个多级指针在其 cv-qualifications 上不同(而不是在第一级上),则是通过等式运算符还是结构良好的关系运算符进行比较?

More generally, if two multi-level pointers differ in their cv-qualifications other than at the first level is comparison via the equality operator or relational operators well-formed?

推荐答案

在C ++ 14之前,这种情况是不正确的,更常见的情况(有些例外)也是不正确的. 缺陷报告1512:指针比较与资格转换有关,它表示:

Before C++14 this case was ill-formed and the more general case with some exceptions was also ill-formed. This is covered in defect report 1512: Pointer comparison vs qualification conversions , which says:

根据5.9 [expr.rel]第2段,描述了指针 比较,

According to 5.9 [expr.rel] paragraph 2, describing pointer comparisons,

对指针操作数(或对指针操作数)执行指针转换(4.10 [conv.ptr])和资格转换(4.4 [conv.qual]) 一个指针操作数和一个空指针常量,或者在两个空指针上 常数,其中至少一个是非整数)以将它们带到 它们的复合指针类型.

Pointer conversions (4.10 [conv.ptr]) and qualification conversions (4.4 [conv.qual]) are performed on pointer operands (or on a pointer operand and a null pointer constant, or on two null pointer constants, at least one of which is non-integral) to bring them to their composite pointer type.

这似乎使以下示例格式错误,

This would appear to make the following example ill-formed,

bool foo(int** x, const int** y) {
   return x < y;  // valid ?
}

因为int **无法转换为const int **,根据 4.4 [conv.qual]第4条的规则 指针比较,当前的实现都接受该示例.

because int** cannot be converted to const int**, according to the rules of 4.4 [conv.qual] paragraph 4. This seems too strict for pointer comparison, and current implementations accept the example.

缺陷报告指出,尽管这是不正确的形式,但实现方式接受了这种比较.此 clang commit 表示将其视为扩展名,并表示gccEDG还将其视为扩展,大概对于Visual Studio也是这种情况.

The defect report points out although this was ill-formed, implementations accepted such comparisons. This clang commit indicates it was treated as an extension and indicates both gcc and EDG also treats this as an extension, presumably this is also the case for Visual Studio.

N3624在标准中对此进行了解决:核心问题1512:指针比较与资格转换,内容为:

本文提出了对工作草案的必要修改 解决核心问题583和1512.特别是,它使

This paper presents the modifications to the Working Draft necessary to resolve core issues 583 and 1512. In particular, it makes

[...]

void g(int **p1, const int**p2)
{
   if (p1 == p2) { ... }
}

格式良好.

还要注意,在开会是接受,注意到这只是整理了现有做法.

Also note that in the meeting it was accepted it was noted that this just codified existing practice.

除对标准的其他更改外,该段添加到5 [expr] 部分的末尾,其中包括新的术语 cv-combined type :

Amongst other changes to the standard, this paragraph was added to the end of section 5 [expr], which includes the new term cv-combined type:

T1和T2两个类型的cv组合类型是类似于T1的T3类型 其简历资格签名(4.4)为:

The cv-combined type of two types T1 and T2 is a type T3 similar to T1 whose cv-qualification signature (4.4) is:

  • 对于每个j> 0,cv3,j是cv1,j和cv2,j的并集;
  • 如果生成的cv3,j与cv1,j或cv2,j不同,则将const添加到每个cv3,k中,且0 <. k < j.
  • for every j > 0, cv3,j is the union of cv1,j and cv2,j ;
  • if the resulting cv3,j is different from cv1,j or cv2,j , then const is added to every cv3,k for 0 < k < j.

[注:给定类似的类型T1 和T2,这种结构确保两者都可以转换为T3. —尾注]两个操作数p1和p2的复合指针类型 分别具有类型T1和T2,其中至少一个是指针 或指向成员类型或std :: nullptr_t的指针是:

[ Note: Given similar types T1 and T2, this construction ensures that both can be converted to T3. —end note ] The composite pointer type of two operands p1 and p2 having types T1 and T2, respectively, where at least one is a pointer or pointer to member type or std::nullptr_t, is:

  • 如果p1和p2均为空指针常量,则为std :: nullptr_t;
  • 如果p1或p2是空指针常量,则分别为T2或T1;
  • 如果T1或T2是指向cv1 void的指针",而另一种类型是指向cv2 T的指针",指向cv12 void的指针",其中cv12是cv1和 cv2;
  • 如果T1是指向cv1 C1的指针"并且T2是指向cv2 C2的指针",其中C1与C2引用相关,或者C2与C1引用相关(8.5.3), T1和T2的cv组合类型或T2的cv组合类型和 分别是T1;
  • 如果T1是指向cv1 U1类型的C1成员的指针",而T2是指向cv2 U2类型的C2成员的指针",其中C1与C2引用相关,则 C2与C1(8.5.3)(T2的cv组合类型和 T1或T1和T2的简历组合类型;
  • 如果T1和T2是相似的多级混合指针和成员类型的指针(4.4),则T1和T2的cv组合类型;
  • 否则,需要确定复合指针类型的程序是错误的.
  • if both p1 and p2 are null pointer constants, std::nullptr_t;
  • if either p1 or p2 is a null pointer constant, T2 or T1, respectively;
  • if T1 or T2 is "pointer to cv1 void" and the other type is "pointer to cv2 T", "pointer to cv12 void", where cv12 is the union of cv1 and cv2 ;
  • if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1 is reference-related to C2 or C2 is reference-related to C1 (8.5.3), the cv-combined type of T1 and T2 or the cv-combined type of T2 and T1, respectively;
  • if T1 is "pointer to member of C1 of type cv1 U1" and T2 is "pointer to member of C2 of type cv2 U2" where C1 is reference-related to C2 or C2 is reference-related to C1 (8.5.3), the cv-combined type of T2 and T1 or the cv-combined type of T1 and T2, respectively;
  • if T1 and T2 are similar multi-level mixed pointer and pointer to member types (4.4), the cv-combined type of T1 and T2;
  • otherwise, a program that necessitates the determination of a composite pointer type is ill-formed.

[示例:

    typedef void *p;
    typedef const int *q;
    typedef int **pi;
    typedef const int **pci;

p和q的复合指针类型是指向const void的指针";这 pi和pci的复合指针类型是指向const的指针 const int". —完示例]

The composite pointer type of p and q is "pointer to const void"; the composite pointer type of pi and pci is "pointer to const pointer to const int". —end example ]

这篇关于给定int ** p1和const int ** p2,p1 == p2格式正确吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆