繁体   English   中英

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

[英]volatile struct = struct not possible, why?

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&'类型的绑定引用到'volatile FOO'会丢弃限定符

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

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

我可以使用memcopy()吗?

如上所述,这是以下问题的副本。

为什么我没有从volatile中提供默认的复制构造函数?

这是不正确的,因为FOO有一个隐式复制构造函数,定义如下:

FOO(FOO const&);

你写FOO test = foo; 使用volatile FOO类型的foo ,调用:

FOO(volatile FOO const&);

但是对引用到非易失性隐式转换的引用 - 易失性是不正确的。

从这里出现两种解决方案:

  1. 不要使易失性转换为非易失性转换;
  2. 定义一个合适的拷贝构造函数或“手动”复制对象成员;
  3. const_cast可以删除volatile限定符,但如果你的底层对象是有效的volatile,那么这是未定义的行为。

我可以使用memcopy()吗?

不,你不能, memcpy与volatile对象不兼容:thre没有带有指针到易失性的重载,没有调用未定义的行为你无能为力。

因此,作为一个结论,如果你不能向FOO添加构造函数,你最好的镜头是定义:

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

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

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

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

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

现在,在你的例子中,应该struct FOO test = foo; 做? 您从未指定是否要先读取foo.a ,然后是foo.b ,最后是foo.c ,或者首先读取foo.c ,然后是foo.b ,最后是foo.a ,或者其他一些订单。

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

struct FOO test;
test.a = foo.a;
test.b = foo.b;
test.c = foo.c;

在这里,您明确指定了访问foo字段的顺序,以避免出现此问题。

您没有提供足够的有关您的问题的详细信息来进行更精确的评估,但是您尝试解决的任何问题的解决方案几乎肯定不会使用volatile “易失性”意味着值可以从您的脚下改变:两个典型的好用例是从UNIX信号处理程序和内存映射寄存器中更改的变量。 易失性对于线程之间共享的变量是不够的,特别是。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM