“来自整数的指针/来自没有强制转换的指针的整数”问题

2023-11-25

这个问题旨在成为整数和指针之间所有初始化/赋值问题的常见问题解答条目。


例如,我想编写将指针设置为特定内存地址的代码0x12345678。但是,当使用 gcc 编译器编译此代码时,我收到“初始化从整数生成指针而不进行转换”警告/错误:

int* p = 0x12345678;

类似地,此代码给出“初始化从指针生成整数而不进行强制转换”:

int* p = ...;
int i =  p;

如果我在变量声明行之外执行相同的操作,则消息是相同的,但显示“赋值”而不是“初始化”:

p = 0x12345678; // "assignment makes pointer from integer without a cast"
i = p;          // "assignment makes integer from pointer without a cast"

使用其他流行编译器进行的测试也会给出错误/警告消息:

  • clang 说“整数到指针转换不兼容”
  • icc 说“类型的值int不能用于初始化类型的实体int*"
  • MSVC (cl) 表示“正在初始化int*间接级别不同int".

问题:上面的例子有效吗?


还有一个后续问题:

这不会给出任何警告/错误:

int* p = 0;

Why not?


不,它不是有效的 C,并且从来都不是有效的 C。这些例子是所谓的违反约束标准的。

该标准不允许您将指针初始化/分配给整数,也不允许将整数初始化/分配给指针。您需要使用强制类型转换手动强制类型转换:

int* p = (int*) 0x1234;

int i = (int)p;

如果您不使用强制转换,则代码不是有效的 C,并且您的编译器不允许在不显示消息的情况下让代码通过。转换运算符声明:C17 6.5.4/3:

约束条件
/--/
除 6.5.16.1 的约束允许的情况外,涉及指针的转换应通过显式强制转换来指定。

6.5.16.1 的规则简单的作业允许对指针进行某些隐式转换,请参阅 C17 6.5.16.1 §1:

6.5.16.1 简单赋值

约束条件

应满足下列条件之一:

  • 左操作数具有原子、限定或非限定算术类型,右操作数具有 算术类型;
  • 左操作数具有结构或联合类型的原子、限定或非限定版本 与权利类型相兼容;
  • 左操作数具有原子、限定或非限定指针类型,并且(考虑类型 左操作数在左值转换后将具有)两个操作数都是指向限定的指针 或兼容类型的非限定版本,并且左侧指向的类型具有所有 右侧指向的类型的限定符;
  • 左操作数具有原子、限定或非限定指针类型,并且(考虑类型 左操作数在左值转换后将具有)一个操作数是指向对象类型的指针, 另一个是指向 void 的限定或非限定版本的指针,以及指向的类型 左边有右边指向的类型的所有限定符;
  • 左操作数是原子、限定或非限定指针,右操作数是空指针 持续的;或者
  • 左操作数的类型为原子、限定或非限定 _Bool,右操作数是指针。

的情况下int* p = 0x12345678;,左操作数是指针,右操作数是算术类型。
的情况下int i = p;,左操作数是算术类型,右操作数是指针。
这些都不符合上述任何限制。

至于为什么int* p = 0;有效,这是一个特殊情况。左操作数是指针,右操作数是空指针常量. 有关空指针、空指针常量和 NULL 宏之间差异的更多信息.


一些注意事项:

  • 如果将原始地址分配给指针,则该指针可能需要volatile合格的,因为它指向硬件寄存器或 EEPROM/闪存位置之类的东西,可以在运行时更改其内容。

  • 即使使用强制转换,也不能保证将指针转换为整数。标准(C17 6.3.2.3 §5 和 §6 说):

An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation. 68)

任何指针类型都可以转换为整数类型。除先前指定的情况外,结果 是实现定义的。如果结果不能用整数类型表示,则行为是 不明确的。结果不必在任何整数类型的值范围内。

信息脚注:

68) The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment.

此外,指针的地址可能比指针所能容纳的地址大。int,就像大多数 64 位系统的情况一样。因此最好使用uintptr_t from <stdint.h>

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

“来自整数的指针/来自没有强制转换的指针的整数”问题 的相关文章

随机推荐

  • 将 NodeList 转换为数组

    我很难转换NodeList到 IE 8 中的数组 以下内容在 Chrome 中完美运行 但在 IE 8 中toArray 不被认为是有效的 NodeList prototype toArray function var a for var
  • AWSGlue AccessDeniedException,状态代码 400

    我正在尝试为数据工程项目构建数据管道 在S3 Glue Athena等的帮助下 我在设置胶水爬虫以对数据进行索引时陷入困境 即使我根据需要设置了角色 但仍然出现以下错误 service AWSGlue statusCode 400 erro
  • 为什么“rgb (224, 226, 213)”是无效的属性值?

    为什么任何浏览器都不能应用此颜色 RGB 规则 HTML
  • Instagram 位置/搜索端点不支持分页,这是否正确?

    我读过几篇关于 Instagram API 一次仅返回 20 个结果的帖子 在很多情况下 人们建议您只需使用分页信息中返回的下一个 URL 即可 我对此没意见 但是返回的 JSON https api instagram com v1 lo
  • 如何查找R包中的所有函数?

    查找包中关联的所有函数的最佳方法是什么 我目前正在浏览 caTools 包 如果我做 caTools or caTools我只是要搜索调用该函数的函数 而不是包中的函数 有没有一种简单的方法可以访问 R gui 中的所有功能 有什么好的方法
  • 集合 <__NSArrayM: 0x76c11b0> 在枚举时发生了变化

    我对 obj c 比较陌生 所以我一定错过了一些东西 但是当敌人与墙壁碰撞时我的程序崩溃了 我已经找到了将敌人从循环中移除的位置 而在循环中 但对于我的一生 我不知道如何解决它 我的代码如下 错误是 allEnemies removeObj
  • getChildView 没有被调用

    我正在制作一个包含自定义 ExpandableListView 适配器的菜单 尽管尝试将我的代码与 API 示例和我在网上看到的任何其他示例 包括多个密切相关的 SO 问题 进行匹配 但我仍然无法使其工作 我知道正在使用适配器 因为正在显示
  • 如何防止rawproto文件生成或自动删除它们?

    Android gradle 插件生成大量 rawproto文件在build android profile目录 它们有什么用 有没有办法阻止这种疯狂或自动删除它们 我已经被它困扰了很长一段时间 现在我注意到有 GB 的内存占用了我小小的
  • 获取 java.rmi.UnmarshalException:无法识别的方法哈希:远程对象不支持方法

    我是 RMI 技术的新手 当我运行 rmi 客户端程序时 出现异常 java rmi UnmarshalException 无法识别的方法哈希 远程对象不支持方法 我使用的是jdk1 5 远程方法的参数是序列化对象 这些是服务器代码 这是远
  • javascript 音频加载

    我做了一个 javascript 音频测试 所有函数都可以在 Opera FF 和 Chrome 中使用 除了 audio oncanplaythrough 和 audio onend 这两个函数在 Chrome 上不起作用 a href
  • Android 设备有唯一的 ID 吗?

    Android 设备是否有唯一的 ID 如果有 使用 Java 访问它的简单方法是什么 Settings Secure ANDROID ID返回 Android ID 作为每个用户都是唯一的64 位十六进制字符串 import androi
  • 重命名多个匹配模式的目录

    我想重命名 basedir 下与名称匹配的所有目录 例如 In basedir 我有 foo bar blah my bar foo some bar foo1 other foo bar 我想重命名所有匹配的目录bar 但我想保留前缀部分
  • 为什么 MATLAB 中的 24.0000 不等于 24.0000?

    我正在编写一个程序 需要删除存储在矩阵中的重复点 问题是 当检查这些点是否在矩阵中时 MATLAB 无法识别矩阵中的它们 尽管它们存在 在下面的代码中 intersections函数获取交点 points 1 points 2 inters
  • Python xlrd:如何转换提取的值?

    好吧 我有一个问题 从我在这里发现的内容来看 我觉得我已经回答了好几次了 然而 作为一个新手 我无法真正理解如何执行真正的基本操作 事情是这样的 我有一个 xls当我使用 xlrd 来获取我只是使用的值时sh cell 0 0 假设 sh
  • 程序“node.exe”无法在 Visual Studio 代码中运行

    当我在 CMD 中运行节点代码时 它工作正常 但在 VS code 终端中出现错误 gt PS D MyApps NodeSession gt npm v 6 4 1 gt PS D MyApps NodeSession gt node v
  • Django AttributeError“datetime.date”对象没有属性“utcoffset”

    我是 Django 的新手 如果问题的解释看起来很奇怪 我很抱歉 我在 Django 项目中创建了一个博客应用程序 模型 py from django db import models class Blog models Model tit
  • 我可以将匿名类型序列化为 xml 吗?

    我知道匿名类型被编译器标记为私有 并且属性是只读的 有没有办法将它们序列化为 xml 无需反序列化 它使用 JSON 我怎样才能用 XML 做到这一点 像这样的事情应该让你开始 class Program static void Main
  • 检查元素是否已被单击或更改

    我有一个愚蠢的问题 我想我已经知道答案 但我想从比我拥有更多 jquery 知识的人那里找到答案 我有一个下拉列表 我想知道是否可以检查 ddl 是否已被单击或更改 例子 If ddl click ddl on change do some
  • Xcode 4.2 如何将一个项目包含到另一个项目中?

    我继续寻找 但找不到关于如何将一个 XCode 项目及其所有子类包含到另一个项目中的清晰而简单的解释 我经常在从网上下载的示例项目中看到类似的东西 但我自己不知道如何做到这一点 在 XCode 中 除了 h 和 m 文件以及文件夹之外 还有
  • “来自整数的指针/来自没有强制转换的指针的整数”问题

    这个问题旨在成为整数和指针之间所有初始化 赋值问题的常见问题解答条目 例如 我想编写将指针设置为特定内存地址的代码0x12345678 但是 当使用 gcc 编译器编译此代码时 我收到 初始化从整数生成指针而不进行转换 警告 错误 int