如何在没有触发警告的情况下将整数值转换为指针地址

时间:2017-07-20 16:15:16

标签: c pointers integer embedded

我有以下变量

uint32_t Value = 0x80

0x80表示存储器中的地址,例如

// Write 2 at address 0x80
*(uint32_t*)((uint32_t)0x80) = 2;

如何将值转换为指针,因此它指向0x80?

uint32_t *Pointer = ?? Value;

此:

(uint32_t*)(uint32_t)Value;

返回:

warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

2 个答案:

答案 0 :(得分:4)

要处理整数到对象指针转换,请使用可选的整数uintptr_tintptr_t类型。函数指针是一个单独的问题。

  

以下类型指定一个无符号整数类型,其属性是指向void的任何有效指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针C11dr 7.20.1.4 1

uintptr_t

然后将void *转换为所需的类型。

#include <stdint.h>
uintptr_t Value = 0x80;
uint32_t *Pointer = (void *) Value;

如果0x80不是从有效uint32_t *派生的,则未定义行为(UB)中的结果。然而,听起来OP是在具有内存映射数据位置的平台上。

答案 1 :(得分:2)

我会为你拼出来的:给出

uint32_t Value = 0x80;

你想要

*((uint32_t *)(uintptr_t)Value) = 2;

类型uintptr_t(如果存在),保证可以在不丢失信息的情况下转换为任意指针类型。它不能保证存在,但在不存在的平台上,如果没有更多的信息,你不能安全地做到这一点。

没有其他类型的官方保证拥有此属性;但是,“cpp plus 1”是正确的size_t 通常也是如此。我甚至会说,任何针对平面内存架构的ABI,使size_t具有此属性,都被错误地指定,但它们确实存在,有时候你必须与他们合作。

最好先用指针类型声明Value

uint32_t *const Value = (uint32_t *)(uintptr_t)0x80;

因为那时你只需要在初始化时编写演员表,而不是在你使用时编写,

*Value = 2;

你可能有很多地方可以使用它。如果发生sizeof(uintptr_t) < sizeof(uint32_t),这也避免了潜在的问题,因为uint32_t从未涉及地址算术;如果从0x80uintptr_t的强制转换实际上截断了常量,编译器可能会抱怨,但这种情况不应该发生在您正以这种方式访问​​的实际内存地址上。