volatile struct = struct不可能,为什么? [英] volatile struct = struct not possible, why?

查看:699
本文介绍了volatile struct = struct不可能,为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

挥发性结构FOO foo;

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

返回0;
}

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


错误:绑定引用类型从'const FOO&'到'volatile FOO'
丢弃限定符


如何复制 volatile结构转换为C ++中另一个 struct (在C ++ 11之前)?



许多人建议仅删除volatile,但是在那种情况下我不能这样做,因为我想在µC中复制当前的SPI-Reg设置,并且制造商标头将其声明为volatile。
我想复制这些设置,因为制造商还提供了一个库来使用SPI进行EnDat通讯,而且我无权访问源代码。由于我必须在运行时更改SPI-Reg-Settings,因此我想轻松地返回到库SPI-settings,而无需再次调用init_endat()-lib fkt(这是未知的,如果我两次调用它会发生什么情况。)



我可以为此使用memcopy()吗?



如所建议的,这是以下问题的副本。 / p>

为什么不从volatile中提供默认的副本构造函数?

解决方案

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

  FOO(FOO const&); 

然后您写 FOO test = foo; 使用 foo 类型为易失FOO 的类型,调用:

  FOO(volatile FOO const&); 

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



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


  1. 不要将挥发转换为非易失;

  2. 定义合适的副本构造函数或手动复制对象成员;

  3. const_cast 可以删除volatile限定符,但这是未定义的行为,如果您的基础对象实际上是易失的,则可以使用它。




我可以为此使用memcopy()吗?


否, memcpy 与易失性对象不兼容:这不是重载,它需要指向易失性的指针,并且如果不调用未定义的行为,您将无能为力。



因此,结论是,如果不能在 FOO 中添加构造函数,则最好的定义是:

  FOO F OO_copy(FOO volatile const&其他)
{
FOO结果;
result.a = other.a;
结果。b =其他。b;
result.c = other.c;
的返回结果;
}

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

  FOO FOO_copy(FOO volatile const& other)
{
FOO结果;
std :: tie(result.a,result.b,result.c)= std :: tie(other.a,other.b,other.c);
的返回结果;
}


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;
}

This won't compile, because struct FOO test = foo; generates an error:

error: binding reference of type 'const FOO&' to 'volatile FOO' discards qualifiers

How can I copy a volatile struct into another struct in C++ (before C++11)?

Many people suggested to just delelte volatile, but I can't do that in that case, because I want to copy the current SPI-Reg setttings inside a µC and this is declared volatile by the manufacturer headers. I want to copy those settings, because the manufactuerer also provides an Library to use the SPI for EnDat-Communication, and I don't have access to the source-code. Since I have to change the SPI-Reg-Settings during runtime I want to easyly get back to the library SPI-settings without calling the init_endat()-lib fkt again (it's unspecified what happens if i call it twice).

Could I possibly use memcopy() for that?

As suggested, this is a copy of the following question.

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

解决方案

This is ill-formed because FOO has an implicit copy constructor defined as:

FOO(FOO const&);

And you write FOO test = foo; with foo of type volatile FOO, invoking:

FOO(volatile FOO const&);

But references-to-volatile to references-to-non-volatile implicit conversion is ill-formed.

From here, two solutions emerge:

  1. don't make volatile to non-volatile conversions;
  2. define a suited copy constructor or copy the object members "manually";
  3. const_cast can remove the volatile qualifier, but this is undefined behavior to use that if your underlying object is effectively volatile.

Could I possibly use memcopy() for that?

No you cannot, memcpy is incompatible with volatile objects: thre is no overload of it which takes pointers-to-volatile, and there is nothing you can do without invoking undefined behavior.

So, as a conclusion, your best shot if you cannot add a constructor to FOO is to define:

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

Or with C++11's 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;
}

这篇关于volatile struct = struct不可能,为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆