我有以下变量
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]
答案 0 :(得分:4)
要处理整数到对象指针转换,请使用可选的整数uintptr_t
或intptr_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
从未涉及地址算术;如果从0x80
到uintptr_t
的强制转换实际上截断了常量,编译器可能会抱怨,但这种情况不应该发生在您正以这种方式访问的实际内存地址上。