给定 int **p1 和 const int**p2 p1 == p2 格式正确吗?

2024-01-11

给定以下函数:

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

clang(回到3.0版本)产生此警告(现场观看 http://melpon.org/wandbox/permlink/lCtOd2FagxDI9n2T):

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) { }
      ~~ ^ ~~

Using -pedantic-errorsflags 将其变成错误。两者都不gcc(返回4.3.6) nor Visual Studio(2013)产生警告,按照标准,是比较:

p1 == p2

形成良好?

更一般地,如果两个多级指针的值不同简历资格除了第一级之外,通过相等运算符或关系运算符进行的比较是否格式良好?


在 C++14 之前,这种情况是格式错误的,并且除了一些例外之外的更一般的情况也是格式错误的。这涵盖在缺陷报告 1512:指针比较与资格转换 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1512,其中说:

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

对指针操作数(或对 一个指针操作数和一个空指针常量,或者两个空指针 常数,至少其中一个是非整数)使它们 它们的复合指针类型。

这似乎会使以下示例格式不正确,

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

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

缺陷报告指出,虽然这是不正确的,但实现接受了这种比较。这铿锵提交 http://llvm.org/klaus/clang/commit/b2cb1cbd727469e1567a6f2535895e6b64e12c35/表示它被视为扩展并表示两者gcc and EDG也把这个当做扩展,想必Visual Studio也是如此。

标准中解决了这个问题N3624:核心问题 1512:指针比较与限定转换 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3624.html,其中说:

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

[...]

and

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

结构良好。

另请注意,在会议被接受 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3622.pdf有人指出,这只是将现有做法编入法典。

在该标准的其他更改中,本段被添加到本节的末尾5 [expr],其中包括新术语CV组合型:

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

  • 对于每个 j > 0,cv3,j 是 cv1,j 和 cv2,j 的并集;
  • 如果生成的 cv3,j 与 cv1,j 或 cv2,j 不同,则将 const 添加到每个 cv3,k (0

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

  • 如果 p1 和 p2 都是空指针常量,则 std::nullptr_t;
  • 如果 p1 或 p2 是空指针常量,则分别为 T2 或 T1;
  • 如果 T1 或 T2 是“指向 cv1 void 的指针”,另一种类型是“指向 cv2 T 的指针”、“指向 cv12 void 的指针”,其中 cv12 是 cv1 和 cv1 的并集 简历2;
  • 如果 T1 是“指向 cv1 C1 的指针”,T2 是“指向 cv2 C2 的指针”,其中 C1 与 C2 引用相关,或者 C2 与 C1 引用相关(8.5.3), T1 和 T2 的 cv 组合型或 T2 和 T2 的 cv 组合型 分别为T1;
  • 如果 T1 是“指向 cv1 U1 类型的 C1 成员的指针”并且 T2 是“指向 cv2 U2 类型的 C2 成员的指针”,其中 C1 与 C2 引用相关或 C2 与 C1 (8.5.3) 相关,是 T2 的 cv 组合类型和 T1或T1和T2的cv组合型;
  • 如果T1和T2是类似的多级混合指针和指向成员类型的指针(4.4),则T1和T2的cv组合类型;
  • 否则,需要确定复合指针类型的程序是格式错误的。

[ 例子:

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

p和q的复合指针类型是“指向const void的指针”;这 pi 和 pci 的复合指针类型是“指向 const 指针的指针” 常量整数”。 —结束示例]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

给定 int **p1 和 const int**p2 p1 == p2 格式正确吗? 的相关文章

  • 迭代变量并查找特定类型实例的技术

    我想迭代进程中内存中的变量 通过插件动态加载 并查找特定类型的实例 以前我可以找到特定类型 或内存中的所有类型 我可以创建类型的实例 我可以获取作为不同类型的字段包含的实例 但我无论如何都不知道只是 搜索 特定类型的实例 一种方法是使用 W
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • POCO HTTPSClientSession 发送请求时遇到问题 - 证书验证失败

    我正在尝试使用 POCO 库编写一个向服务器发出 HTTPS 请求的程序 出于测试目的 我正在连接到具有自签名证书的服务器 并且我希望允许客户端进行连接 为了允许这种情况发生 我尝试安装InvalidCertificateHandler这是
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • 如何从 C# 控制器重定向到外部 url

    我使用 C 控制器作为网络服务 在其中我想将用户重定向到外部网址 我该怎么做 Tried System Web HttpContext Current Response Redirect 但没有成功 使用控制器的重定向 http msdn
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 通过 NHibernate 进行查询,无需 N+1 - 包含示例

    我有一个 N 1 问题 我不知道如何解决它 可以在这个问题的底部找到完全可重复的样本 因此 如果您愿意 请创建数据库 设置 NUnit 测试和所有附带的类 并尝试在本地消除 N 1 这是我遇到的真实问题的匿名版本 众所周知 这段代码对于帮助
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 当模板类不包含可用的成员函数时,如何在编译时验证模板参数?

    我有以下模板struct template
  • System.Runtime.InteropServices.COMException(0x80040154):[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 C 项目中遇到异常 System Runtime InteropServices COMException 0x80040154 检
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • 为什么拆箱枚举会产生奇怪的结果?

    考虑以下 Object box 5 int int int box int 5 int nullableInt box as int nullableInt 5 StringComparison enum StringComparison
  • 转到定义:“无法导航到插入符号下的符号。”

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我今天突然开始在我的项目中遇到一个问题 单击 转到定义 会出现一个奇怪的错误 无法导航到
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder

随机推荐