C ++结构和挥发性

时间:2014-05-27 14:16:17

标签: c++ struct volatile

我有一些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问题对我来说更令人困惑,因为结构是按值传递的,所以返回的值作为副本自然会失去它的波动性?对于设定的情况,当数据被另一个过程改变时,波动性肯定更重要 - 我真的不知道写入数据位置时的易失性意味着什么。

注意:为了这个例子的目的,代码片段被删减了,那里有各种锁定和边界检查代码:)

2 个答案:

答案 0 :(得分:0)

对于getIndexNode,答案似乎相当简单:const_cast在返回之前消除波动性,因为那是你想要的语义。请注意,只要volatile指针指向的内存最初未声明为volatile,就可以很好地定义它。

对于复制赋值运算符,您可以尝试将其设为volatile,但是您还没有显示足够的代码来确定是否可以解决您的问题。例如index_node_t& index_node_t::operator=(const index_node_t&) volatile

答案 1 :(得分:0)

抛弃波动性永远不安全;您只能使用标记为volatile的成员函数。

然而,这样做并不能保证安全;操作可能是非原子的,因此线程切换可以重新启动它们。您还必须确保通过某种锁定机制或其他方式,当您使用这些易失性结构之一时,操作将完成,而不会在操作期间通过其他内容更改结构的数据。

在共享内存中使用这些结构可能会更容易,但是使用一些可以通过OS函数原子读取和写入的bloc数据(如果存在这样的话)。