C 如何将掩码应用于常量void*地址?
我在一个嵌入式目标上工作,希望定义内存池 内存地址表示为C 如何将掩码应用于常量void*地址?,c,casting,memory-address,C,Casting,Memory Address,我在一个嵌入式目标上工作,希望定义内存池 内存地址表示为void*。然而,在特定情况下,这些地址是缓存的,我想取消缓存以直接获得“真实”的硬件地址 我想定义内存\u区域开头的地址(它只是一个标记): 不幸的是,GCC不允许我这样做: error: invalid operands to binary | (have 'const void *' and 'long unsigned int') 在绝望中,我试着: const void * real_address = (void*)
void*
。然而,在特定情况下,这些地址是缓存的,我想取消缓存以直接获得“真实”的硬件地址
我想定义内存\u区域
开头的地址(它只是一个标记):
不幸的是,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
我真的很想保持常数
以确保安全:这是可以实现的吗
[编辑]
- 我在Linux上使用的是
v4.9(带有gcc
和许多-std=gnu99
标志)-Wxxx
- 摘录自
文件,变量为“全局”.h
const void * real_address
这意味着“real_address是指向未知类型的常量内存的指针”。如果您希望指针也不可修改(除了它指向的内容之外),可以执行以下操作:
const void * const real_address
但是,您将无法按照需要在函数中初始化它。我想您可以抛弃函数中的常量,但这在C语言中甚至可能不合法。只需定义一个。它不能被意外地改变
#define real_address ( (void*)( (uint32_t)virtual_address | UNCACHE_MASK ) )
每次使用一两条额外指令并不十分昂贵
还要向virtual\u address
变量添加一个const关键字,这样它就无法更改
const void* const virtual_address = ...
如果定义函数中的
real\u address
,则无法在函数中为其赋值void const*const
@user694733:谢谢,我修正了我的答案以反映这一点。我最终选择放弃const
,只需将其声明为全局并在函数中设置地址。在这里,这可能无关紧要,您知道您的arch是32位的,但通常应该使用uintpttr\u t
来强制转换指向整数的指针。(因为有一天你把你的东西移植到64位,你会后悔的:)好的,谢谢你的提示!我不认为“缓存”在这里意味着你认为它的功能。听起来好像你在谈论虚拟地址,这不是一个缓存概念。缓存不会更改地址。您可能对以下问题的答案感兴趣:您收到的第二个警告,因为您可能将虚拟_地址作为全局地址,并尝试使用非常量表达式初始化它。因此,您的代码中有两个不同的问题。很好的提示,它实际上解决了我的代码摘录中的问题,但是我正在寻找优化,real\u address
用于其他计算,我希望避免这些额外的指令。如果这种重新计算真的是一个瓶颈(我对此表示怀疑)您可以尝试在变量的开头存储该值一次。如果您经常使用该变量,它在缓存中应该始终是热的,并且在重新加载时不会产生太多开销。
const void* const virtual_address = ...