volatile struct = struct不可能,为什么?

时间:2018-03-19 16:27:54

标签: c++ struct volatile

struct FOO{
    int a;
    int b;
    int c;
};

volatile struct FOO foo;

int main(void)
{
    foo.a = 10;
    foo.b = 10;
    foo.c = 10;
    struct FOO test = foo;

    return 0;
}

这不会编译,因为 struct FOO test = foo; 生成错误:

  

错误:'const FOO&'类型的绑定引用'挥发性FOO'   丢弃限定符

如何将volatile struct复制到C ++中的另一个struct中(在C ++ 11之前)?

许多人建议只删除volatile,但在这种情况下我不能这样做,因为我想在μC内复制当前的SPI-Reg设置,并且这被制造商标题声明为volatile。 我想复制这些设置,因为制造商还提供了一个库来使用SPI进行EnDat-Communication,而我无法访问源代码。由于我必须在运行期间更改SPI-Reg-Settings,因此我希望能够轻松地返回到库SPI设置,而无需再次调用init_endat() - lib fkt(如果我将其调用两次,则未指定会发生什么情况。)

我可以使用memcopy()吗?

根据建议,这是以下问题的副本。

Why am I not provided with a default copy constructor from a volatile?

3 个答案:

答案 0 :(得分:23)

这是格式错误的,因为FOO有一个隐式复制构造函数,定义为:

FOO(FOO const&);

您使用类型FOO test = foo;的{​​{1}}撰写foo,并调用:

volatile FOO

但引用到非易失性隐式转换的引用易失性。

从这里开始,两个解决方案出现了:

  1. 不要将易失性转换为非易失性转换;
  2. 定义适合的复制构造函数或“手动”复制对象成员;
  3. FOO(volatile FOO const&); 可以删除volatile限定符,但如果你的底层对象实际上是volatile,那么这是未定义的行为。
  4.   

    我可以使用memcopy()吗?

    不,你不能,const_cast与易失性对象不兼容:thre不会引起指针到易失性的重载,如果不调用未定义的行为,你就无法做任何事情。

    因此,作为结论,如果您无法向memcpy添加构造函数,那么最好的方法是定义:

    FOO

    或者使用C ++ 11的std::tie

    FOO FOO_copy(FOO volatile const& other)
    {
        FOO result;
        result.a = other.a;
        result.b = other.b;
        result.c = other.c;
        return result;
    }
    

答案 1 :(得分:19)

要给出答案的另一种方法,解决为什么这没有意义,而不仅仅是C ++标准所说的无效:

volatile的重点在于,您可以精确控制何时访问哪个变量。这意味着给定volatile int i, j;i = 1; j = 2;j = 2; i = 1;不会做同样的事情。编译器无法自由地将一个转换为另一个。这同样适用于读取:给定volatile int i, j; int x, y;x = i; y = j;y = j; x = i;不做同样的事情。 volatile的存在意味着访问必须完全您指定的顺序发生。

现在,在您的示例中,struct FOO test = foo;应该做什么?您从未指定是先阅读foo.a,然后是foo.b,最后是foo.c,还是先阅读foo.c,然后foo.b,最后{ {1}},或者其他一些订单。

如果您愿意,可以这样做:

foo.a

在这里,您明确指定了对struct FOO test; test.a = foo.a; test.b = foo.b; test.c = foo.c; 字段的访问顺序,以避免出现此问题。

答案 2 :(得分:3)

您尚未提供有关问题的足够详细信息以提供更准确的评估,但您尝试解决的任何问题的解决方案几乎肯定不会使用const person = { age: 18, size: '1m74', eyeColor: 'blue', }; Object.keys(person).forEach((x) => { const obj = { [x]: person[x], }; console.log(obj); });。 "挥发性"意味着值可以从你的脚下改变:两个典型的好用例是从UNIX信号处理程序和内存映射寄存器中改变的变量。易失性对于线程之间共享的变量是不够的,特别是。

您收到此错误的原因是您的编译器正在尝试查找永远不会自动生成的volatile复制构造函数。