【问题标题】:Why is casting from int to void * allowed?为什么允许从 int 转换为 void *?
【发布时间】:2015-04-23 07:22:54
【问题描述】:

为什么在 C 中允许从 void* 转换为 int 以及反之亦然? 除了pthread,它还用在什么地方?

【问题讨论】:

  • 只是因为它在 pthread_create 中很方便。 & void* & int 通常具有相同的大小 - 4 个字节。但你不应该假设这一点。理想情况下,您应该将整数指针传递给它,而不是值。但是对于数字常量,我们使用这个技巧来传递值。
  • @anishane: "void* & int have usually same size - 4 bytes" - 这是一个非常危险的假设 - 在过去的 32 位时代,它曾经是正确的,但现在大多数桌面和服务器操作系统都是 64 位的(LP64 = 4 byte int 和 8 字节指针)。
  • 在 C 中允许从 int 转换为指针的一个原因是代码可以访问 memory mapped I/O

标签: c pointers casting


【解决方案1】:

允许,但行为是实现定义的。

有时,在某些情况下(在特定平台/架构上),此规定可能对于使用运算符涉及内存地址的快速和肮脏黑客/技巧很有用需要int 操作数。 [例如:XOR 操作]。可用于内存有限的嵌入式设备的内存优化。

引用有关功能的标准,

将指针转换为整数或将整数转换为指针的映射函数旨在与执行环境的寻址结构保持一致。

相关阅读:来自c11,第6.3.2.3章,

第 5 段:

整数可以转换为任何指针类型。除非前面指定,否则结果是实现定义的,可能未正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。

和第 6 段:

任何指针类型都可以转换为整数类型。除非前面指定,结果是实现定义的。如果结果不能以整数类型表示,则行为未定义。结果不必在任何整数类型的值范围内。

【讨论】:

    【解决方案2】:

    以下标准参考定义了这些转换。如您所见,它们是实现定义的。仅当您知道自己在做什么并了解您的平台时,您才应该进行转化。

    6.3.2.3 指针

    1. 整数可以转换为任何指针类型。除先前规定外, 结果是实现定义的,可能没有正确对齐,可能不指向 引用类型的实体,可能是陷阱表示。

    2. 任何指针类型都可以转换为整数类型。除先前规定外, 结果是实现定义的。如果结果不能用整数类型表示, 行为未定义。结果不必在任何整数的值范围内 输入

    【讨论】:

      猜你喜欢
      • 2015-03-12
      • 2013-04-23
      • 2020-06-24
      • 2018-06-10
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      相关资源
      最近更新 更多