如何将掩码应用于const void *地址?

时间:2014-10-02 11:45:20

标签: c casting memory-address

我在嵌入式目标上工作,并希望定义内存池。

内存地址表示为void*。但是在特定情况下,这些地址被缓存,我想要解除它们以直接获得“真正的”硬件地址。

我想定义memory_area开头的地址(这只是一个标记):

#define UNCACHE_MASK 0xABCDEF12UL // Value of the mask to apply
extern uint32_t memory_area; // Global, defined somewhere else
const void * virtual_address = &memory_area; // OK
const void * real_address = 
    (void*)(virtual_address | UNCACHE_MASK); // guilty line

不幸的是,GCC不允许我这样做:

error: invalid operands to binary | (have 'const void *' and 'long unsigned int')

绝望中我试过:

const void * real_address = 
    (void*)(((uint32_t)virtual_address) | UNCACHE_MASK); // guilty line

徒劳:

error: initializer element is not constant

我真的想保留const以确保安全:它是否可以实现?

[编辑]

  • 我在Linux上使用gcc v4.9(带-std=gnu99和许多-Wxxx标志)。
  • 摘录来自.h文件,变量是“全局”。

2 个答案:

答案 0 :(得分:5)

只需进行定义即可。它不会被意外改变。

#define real_address  ( (void*)( (uint32_t)virtual_address | UNCACHE_MASK ) )

每次使用额外的指令或两次不是很贵。

还要在virtual_address变量中添加一个const关键字,因此无法更改。

const void* const virtual_address = ...

答案 1 :(得分:2)

您可以使用函数内的按位OR表达式来指定它。你不能像你所示的那样在全局范围内进行初始化,因为编译器确实不知道这个值(可能在C ++中,但在C中却没有)。如果添加强制转换并在函数范围内移动赋值,它将起作用。

当你这样说时:

const void * real_address

这意味着" real_address是指向未知类型的常量内存的指针。"如果您希望指针也不可修改(除了它指向的内容),您可以这样做:

const void * const real_address

但是,您无法根据需要在函数内初始化它。我想你可以抛弃函数内部的常量,但这在C语言中可能不合法。