C++结构和挥发物
C++ structs and volatiles
我有一些C代码,我希望向C++过渡,作为第一步,我正在尝试用C++编译器(现在是g++(编译。
它为IPC使用一些共享内存段,指向这些内存段的指针被声明为volatile:
volatile my_rec_t *myRec;
(其中my_rec_t只是一个普通的旧数据结构,myRec是作为这些结构的数组访问的(。
我对这个数据结构的波动性有一些问题:C++似乎比C需要更多的铸造,我不太确定我为什么。。。
有一些自动生成的访问器函数可以获取/设置共享内存结构中的字段(目前都是C样式代码(。这适用于基元数据类型,但如果my_rec_t
中的一个字段本身是结构,则会产生错误:
int setIndexNode( int myRecNo, index_node_t indexNode )
{
myRec[ myRecNo ].indexNode = indexNode;
return TRUE;
}
在C++中,这会生成以下内容:error: passing 'volatile index_node_t' as 'this' argument of 'index_node_t& index_node_t::operator=(const index_node_t&)' discards qualifiers
。为了获得价值:
index_node_t getIndexNode( int myRecNo )
{
return myRec[ myRecNo ].indexNode;
}
错误为error: no matching function for call to 'index_node_t::index_node_t(volatile index_node_t&)'
get问题更让我困惑,因为结构是按值传递的,所以作为副本的返回值自然会失去它的波动性?对于既定的情况,在读取数据以防数据被另一个进程更改方面,波动性肯定更重要——我真的不知道在写入数据位置时波动性意味着什么。
注意:为了这个例子的目的,代码片段被削减了,其中有各种锁定和边界检查代码:(
对于getIndexNode
,答案似乎相当简单:const_cast
在返回波动性之前先消除波动性,因为这是您想要的语义。请注意,只要volatile
指针所指向的内存最初不是声明为volatile
的,那么将其丢弃就可以得到很好的定义。
对于副本分配运算符,您可以尝试将其设置为volatile
,尽管您还没有显示足够的代码来确定这是否能解决您的问题。例如index_node_t& index_node_t::operator=(const index_node_t&) volatile
。
抛弃波动性永远都不安全;只能使用标记为volatile
的成员函数。
然而,仅仅这样做并不能保证安全;这些操作可能是非原子的,因此线程开关可以重新激活它们。您还必须通过某种锁定机制或其他方式确保,当您使用这些易失性结构中的一个时,操作将完成,而结构的数据在操作过程中不会被其他东西更改。
事实证明,在共享内存中不使用这些结构,而是使用一些可以通过操作系统函数原子读取和写入的区块数据(如果存在这样的东西(可能会更容易。
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 什么可以用来在 C++ 中保存图形等结构(Python pickle 等效物)
- 可能是嵌套结构化结合物
- 如何初始化具有非易失性结构的挥发性结构
- 为什么要在 C++ 结构中添加填充物
- 包含挥发性结构的联合
- 复制(非浅层或深层)用于C/C++/Java等同物中的结构.复制到所有成员都指向完全相同内存的变量
- 露天铺筑物的结构