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

Coc*_*nop 4 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
Run Code Online (Sandbox Code Playgroud)

不幸的是,GCC不会让我这样做:

error: invalid operands to binary | (have 'const void *' and 'long unsigned int')
Run Code Online (Sandbox Code Playgroud)

无奈之下我试过:

const void * real_address = 
    (void*)(((uint32_t)virtual_address) | UNCACHE_MASK); // guilty line
Run Code Online (Sandbox Code Playgroud)

徒然:

error: initializer element is not constant
Run Code Online (Sandbox Code Playgroud)

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

[编辑]

  • 我在Linux上使用gccv4.9(带有-std=gnu99很多-Wxxx标志).
  • 摘录来自.h文件,变量是"全局的".

250*_*501 5

简单地定义一下.它不会被意外改变.

#define real_address  ( (void*)( (uint32_t)virtual_address | UNCACHE_MASK ) )
Run Code Online (Sandbox Code Playgroud)

每次使用额外的指令或两个并不是非常昂贵.

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

const void* const virtual_address = ...
Run Code Online (Sandbox Code Playgroud)

  • 如果此重新计算确实是一个瓶颈(我对此表示怀疑),则可以尝试在变量的开头存储一次该值。如果经常使用该变量,则该变量在缓存中应始终很热,并且在重新加载时不会增加太多开销。 (2认同)