How to apply a mask to a const void* address?

不想你离开。 提交于 2020-01-14 10:19:26

问题


I work on an embedded target and want to define memory pools.

Memory addresses are represented as void*. However in a particular case, those addresses are cached and I want to uncache them to get directly the "real" hardware address.

I want to define the address of the beginning of memory_area (which is just a marker):

#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

Unfortunately, GCC won't let me do this:

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

In desperation I tried :

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

In vain:

error: initializer element is not constant

I really want to keep the const for safety : is it achievable ?

[EDIT]

  • I am using gcc v4.9 (with -std=gnu99 and a lot of -Wxxx flags) on Linux.
  • The excerpt is from a .h file, variables are "global".

回答1:


You can assign this using your bitwise-OR expression inside a function. You cannot do the initialization at global scope as you have shown, because indeed the value is not known to the compiler (maybe in C++, but not in C). If you add the casts and move the assignment inside a function scope, it will work.

When you say this:

const void * real_address

It means "real_address is a pointer to constant memory of unknown type." If you want the pointer to also not be modifiable (in addition to what it points to), you can do this:

const void * const real_address

But then you won't be able to initialize it inside a function as you need to do. I suppose you could cast away the constness inside the function, but this may not even be legal in C.




回答2:


Simply make a define. It cannot be accidentally changed.

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

The extra instruction or two per usage aren't very expensive.

Also add a const keyword to the virtual_address variable, so it cannot be changed.

const void* const virtual_address = ...


来源:https://stackoverflow.com/questions/26160080/how-to-apply-a-mask-to-a-const-void-address

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!