C11 中是否有定义的方法来进行指针减法?

2024-03-03

有没有一种方法可以在 C11 中将一个指针与另一个指针相减,并始终定义结果?

该标准规定,如果结果不能表示为 ptrdiff_t 类型,则行为未定义。

我对依赖于静态断言的解决方案持开放态度,该解决方案有望在现代通用 32 或 64 位环境中传递合理的实现。我想避免依赖任何类型的运行时检查的解决方案。

如果指向的类型的大小大于 1,我可以静态断言 size_t 和 ptrdiff_t 具有相同数量的非填充位。这个部分解决方案依赖于我不确定的两件事,因此任何对此的反馈都将提供部分答案:

  1. 可以预期,在现代通用 32 或 64 位环境中的合理实现中,ptrdiff_t 至多比 size_t 少一位值位。

  2. 我对标准的理解是正确的,因为两个指向大小大于 1 的对象的指针之间的差异是定义的,即使如果指针被转换为字符指针,相同的差异将是未定义的。这种理解似乎与委员会草案中的脚注106不一致,但我的理解是脚注不具有规范性。


根据标准

仅当两个指针都指向同一对象(其中包括“最后一位”指针)时,才可以对指针进行减法。

减法uintptr_t or intptr_t不一定有意义,因为根据标准,没有必须定义从指针到整数的转换的特定方法。尤其,

  • 考虑分段内存模型中的远指针,其中可能有不止一种方式来表示给定地址(例如,在 x86 上,段 + 偏移量)。

  • 考虑具有被处理器忽略的位的指针。 (例如,Motorola 68000 处理器,它具有 32 位指针,但高 8 位被忽略。)

因此,不幸的是,根据标准,没有办法可移植地做到这一点。

记住: size_t是物体的最大尺寸。这是not地址空间的大小。这是完全合法的size_t范围更小uintptr_t和朋友。与相同ptrdiff_t: 这是完全合法的ptrdiff_t范围小于uintptr_t。例如,想象一下分段内存模型,您无法分配大于段的任何内容,在这种情况下,size_t and ptrdiff_t可能能够表示段的大小,但不能表示地址空间的大小。

根据实践

在您使用的计算机(现代 32 位和 64 位计算机)上,uintptr_t仅包含指针地址。减去掉。这是实现定义的但不是未定义的行为。

不要在不进行强制转换的情况下减去原始指针,除非它们指向同一个对象,或者指向该对象之后的地址。当您使用指针算术时,编译器可以并且将会做出别名假设。不仅你的程序在“技术上”是错误的,而且编译器在这里产生错误代码的历史也很长。

关于指针指向同一个对象到底意味着什么,现在存在一些争论,但我上次检查时这个争论尚未解决。

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

C11 中是否有定义的方法来进行指针减法? 的相关文章

  • C# 创建函数队列

    我写了一个名为 QueueManager 的类 class QueueManager Queue functionsQueue public bool IsEmpty get if functionsQueue Count 0 return
  • 起订量要求?违背了目的?

    是否需要虚拟化您想要模拟的所有属性访问器就违背了模拟的目的 我的意思是 如果我必须修改我的对象并虚拟化我想要模拟的每个访问器 我难道不能继承我的类并自己模拟它吗 你的问题非常有效 但如果你仔细想想 没有其他方法可以模拟课程 如果你采用一个接
  • 为什么 VB.NET 和 C# 中针对值检查 null 存在差异?

    In VB NET http en wikipedia org wiki Visual Basic NET有时候是这样的 Dim x As System Nullable Of Decimal Nothing Dim y As System
  • 如何将十六进制字符串转换为十六进制数字[重复]

    这个问题在这里已经有答案了 可能的重复 如何将十六进制字符串转换为有符号整数 https stackoverflow com questions 3705429 how do i convert hex string into signed
  • 访问“if”语句之外的变量

    我怎样才能使insuranceCost以外可用if陈述 if this comboBox5 Text Third Party Fire and Theft double insuranceCost 1 在 if 语句之外定义它 double
  • 存储过程上的 OdbcCommand - 输出参数上出现“未提供参数”错误

    我正在尝试执行存储过程 通过 ODBC 驱动程序针对 SQL Server 2005 但收到以下错误 过程或函数 GetNodeID 需要参数 ID 但未提供该参数 ID 是我的过程的 OUTPUT 参数 在存储过程中指定了一个输入 mac
  • 单线程公寓问题

    从我的主窗体中 我调用以下命令来打开一个新窗体 MyForm sth new MyForm sth show 一切都很好 但是这个表单有一个组合框 当我将其 AutoCompleteMode 切换为建议和追加时 我在显示表单时遇到了这个异常
  • 默认值 C# 类 [重复]

    这个问题在这里已经有答案了 我在控制器中有一个函数 并且我收到表单的信息 我有这个代码 public Actionresult functionOne string a string b string c foo 我尝试将其转换为类似的类
  • 更改 IdentityServer4 实体框架表名称

    我正在尝试更改由 IdentityServer4 的 PersistedGrantDb 和 ConfigurationDb 创建的默认表名称 并让实体框架生成正确的 SQL 例如 而不是使用实体IdentityServer4 EntityF
  • C#中Enum中定义的value__是什么

    What value 可能在这里 value MSN ICQ YahooChat GoogleTalk 我运行的代码很简单 namespace EnumReflection enum Messengers MSN ICQ YahooChat
  • .NET JIT 编译的代码缓存在哪里?

    NET 程序首先被编译为 MSIL 代码 当它被执行时 JIT编译器会将其编译为本机机器代码 我想知道 这些JIT编译的机器代码存储在哪里 它只存储在进程的地址空间中吗 但由于程序的第二次启动比第一次快得多 我认为即使在执行完成后 该本机代
  • 如何使用收益返回和递归获得字母的每个组合?

    我有几个像这样的字符串列表 可能有几十个列表 1 A B C 2 1 2 3 3 D E F 这三个仅作为示例 用户可以从几十个具有不同数量元素的类似列表中进行选择 再举个例子 这对于用户来说也是一个完全有效的选择 25 empty 4 1
  • 纯虚函数可能没有内联定义。为什么?

    纯虚函数是那些虚函数并且具有纯说明符 0 第 10 4 条第 2 款C 03 的内容告诉我们什么是抽象类 顺便说一句 如下 注意 函数声明不能 同时提供纯说明符和定义 尾注 示例 struct C virtual void f 0 ill
  • 如何将对象转换为传递给函数的类型?

    这不会编译 但我想做的只是将对象转换为传递给函数的 t public void My Func Object input Type t t object ab TypeDescriptor GetConverter t ConvertFro
  • C++ [Windows] 可执行文件所在文件夹的路径[重复]

    这个问题在这里已经有答案了 我需要访问一些文件fstream在我的 Windows 上的 C 应用程序中 这些文件都位于我的exe文件所在文件夹的子文件夹中 获取当前可执行文件的文件夹路径的最简单且更重要的 最安全的方法是什么 Use 获取
  • 使用 Chrome 和 Selenium 设置 LocalStorage

    我正在尝试使用 OpenQA Selenium 和 Chrome 设置本地存储键和值 我认为这相当微不足道 但我似乎无法让它发挥作用 我对 C 很陌生 所以我可能错过了一些东西 无论如何 我有这个功能 public static void
  • 从有符号字符转换为无符号字符然后再转换回来?

    我正在使用 JNI 并有一个 jbyte 类型的数组 其中 jbyte 表示为有符号字符 即范围从 128 到 127 jbyte 表示图像像素 对于图像处理 我们通常希望像素分量的范围为0到255 因此 我想将jbyte值转换为0到255
  • 如何设置 CMake 与 clang 交叉编译 Windows 上的 ARM 嵌入式系统?

    我正在尝试生成 Ninja makefile 以使用 Clang 为 ARM Cortex A5 CPU 交叉编译 C 项目 我为 CMake 创建了一个工具链文件 但似乎存在错误或缺少一些我无法找到的东西 当使用下面的工具链文件调用 CM
  • g++ C++0x 枚举类编译器警告

    我一直在将可怕的 C 类型安全伪枚举重构为新的 C 0x 类型安全枚举 因为它们是way更具可读性 不管怎样 我在导出的类中使用它们 所以我明确地将它们标记为导出 enum class attribute visibility defaul
  • 新的 .NET 6 控制台模板中的 C# 函数重载不起作用

    我在尝试重载该函数时遇到错误Print object in the 新的 NET 6 C 控制台应用程序模板 https learn microsoft com en us dotnet core tutorials top level t

随机推荐

  • 如何删除数据库,错误5030数据库无法锁定

    我正在尝试删除 SQL Server 2005 中的现有数据库 我的第一次尝试产生了以下错误 5030 数据库不能独占 锁定以执行操作 此后我已经杀死了所有正在访问数据库的进程 我还删除了它之前涉及的复制订阅 除了 SQL Server 进
  • 未出现写入 ILogger 的 Serilog (Azure Functions V2)

    我已安装 Serilog 并配置为将日志事件数据写入 MS SQL Server for Azure Function 中的表 系统日志和静态类本身写入的日志显示在表中 但是当我尝试使用 Extensions Logging ILogger
  • 核心数据和分页

    我有一个包含 50 000 条记录的数据库 我正在使用核心数据从搜索中获取记录 一次搜索可以轻松返回 1000 条记录 使用 core data 和 uitableview 来分页这些记录需要什么 我想一次显示 100 条记录 并在查看 1
  • iOS 中如何将字符串的一部分加粗?

    我想让文本字符串的某些部分变为粗体 Eg 这就是要大胆 这是正常的字符串 在Android中 可以通过使用可生成字符串轻松实现 iOS 中的等价物是什么 是的 可以通过以下方式实现NSAttributedString https devel
  • Laravel 用户特定的缓存

    我从来没有对缓存做过太多事情 但现在我正在尝试尝试一下 我有一个返回大量数据的仪表板 为了减轻负载 我像这样缓存数据 return cache gt rememberForever something function return aut
  • EF Core 2.2,将字符串参数传递给 FromSql 语句

    public List
  • 如何一次反编译多个jar?

    好吧 我想主题已经说明了一切 理想的解决方案将找到某个文件夹中的所有 jar 它们可能位于子文件夹中 并将找到的所有源写入单个 src 目录 当然还要维护包文件夹 具体用例 反编译所有 Eclipse 插件 jar 下载JAD反编译器 ht
  • 在 PHPUnit 中,如何模拟父方法?

    我想测试一个调用同名父方法的类方法 有没有办法做到这一点 class Parent function foo echo bar class Child function foo foo parent foo return foo class
  • 无法修复“语法错误,‘foreach’语句仅在源级别为 1.5 时可用”

    我正在编写一个 Java 代理 它使用参数化集合类型和增强的 for 循环 然后 Domino Designer 8 5 3 告诉我通过快速修复操作将项目的合规性级别更改为 1 5 如果我这样做 项目就会重建 并且不会发生任何变化 如果我转
  • Shopify.onItemAdded 更新#cart 和 cart.item.count

    我正在尝试在 Shopify 中制作一个 ajaxed 购物车 我已使产品页面将商品添加到购物车 而无需刷新或转到购物车页面 要查看购物车 您可以单击输入或带有 cart show 的链接 因此我将其添加到 添加到购物车 输入中
  • 使用 Pyspark 进行单元测试:未关闭的套接字警告

    我想使用 PySpark 进行单元测试 测试本身有效 但是对于我得到的每个测试 ResourceWarning unclosed
  • 如何使目录可写? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 如何从 OS X 终端使目录可写 chmod w
  • Windows 窗体设计器破坏了窗体布局

    今天早上 我在 Visual Studio Windows 窗体设计器中偶然发现了一个奇怪的问题 我有一份表格 现在已经使用了大约一个月 没有任何变化 在应用程序中看起来像这样 文本变得不可读 因为我不完全确定这里的法律含义 现在从今天开始
  • gpg --homedir 更改目录不起作用

    我们有一台 Windows Server 2008 R2 服务器 我们安装了 gpg4win 并且它可以工作 我们可以创建公钥和私钥 并为那些拥有我们的公钥的人解密消息 问题 gnu 安装默认为我的用户配置文件 我们希望它位于通用配置文件下
  • iOS - 以编程方式设置 UIContainerView 的嵌入式 UIViewController

    我有一个UIViewController with a UIContainerView里面 根据某个条件是否成立 我想以编程方式将容器视图的嵌入视图设置为不同的UIViewController 我注意到你只能用一个嵌入转场来设置一个UIVi
  • Google Map API 方向三角形图标不明确

    I am using Google Map API V3 to show the vehicle traveled path and its route directions But by google direction icon its
  • 如何通过内键对多维数组进行排序

    我有一个巨大的数组 是从 BattleField Bad Company 2 的 API 中提取的 并且士兵统计数据可以作为多维数组提取 每个士兵都有一个内部数组 但是 API sormats 它按名称字母顺序对士兵进行排序 我想按等级对它
  • Count() 列表中的特定属性#

    if gardenvlist Count getava Count else if oceanvlist Count getava Count else if cityvlist Count getava Count gardenvlist
  • 启动活动时出现 NullpointerException

    我有一个可以执行此操作的数组列表 ArrayList
  • C11 中是否有定义的方法来进行指针减法?

    有没有一种方法可以在 C11 中将一个指针与另一个指针相减 并始终定义结果 该标准规定 如果结果不能表示为 ptrdiff t 类型 则行为未定义 我对依赖于静态断言的解决方案持开放态度 该解决方案有望在现代通用 32 或 64 位环境中传