复制C volatile bitfield结构的构造函数

时间:2017-07-25 10:06:14

标签: c++ keil armcc

美好的一天

我正在尝试在C ++ 11项目中使用C SD驱动程序/文件系统库(Keil MDK)。它由Keil MDK 5.23中的Pack经理添加。我正在使用ARMCC 5.06u4进行编译

我收到警告class "_ARM_MCI_STATUS"没有合适的复制构造函数"这是奇怪的,因为它声明的标题有extern "C" {

默认情况下,包没有选项将其设置为C或C ++,但我手动将文件添加为C文件。还是个问题。

结构在extern "C" {内声明为:

typedef volatile struct _ARM_MCI_STATUS {
    uint32_t command_active   : 1;        ///< Command active flag
    uint32_t command_timeout  : 1;        ///< Command timeout flag (cleared on start of next command)
    uint32_t command_error    : 1;        ///< Command error flag (cleared on start of next command)
    uint32_t transfer_active  : 1;        ///< Transfer active flag
    uint32_t transfer_timeout : 1;        ///< Transfer timeout flag (cleared on start of next command)
    uint32_t transfer_error   : 1;        ///< Transfer error flag (cleared on start of next command)
    uint32_t sdio_interrupt   : 1;        ///< SD I/O Interrupt flag (cleared on start of monitoring)
    uint32_t ccs              : 1;        ///< CCS flag (cleared on start of next command)
    uint32_t reserved         : 24;
} ARM_MCI_STATUS;

在以下位置返回结构时出现问题:

static ARM_MCI_STATUS GetStatus (MCI_RESOURCES *mci) {
  return mci->info->status;
}

status声明为ARM_MCI_STATUS status;的位置。我不明白为什么它应该成为一个问题。

如果我在没有--cpp的情况下编译,那么它会毫无问题地编译。

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

在C ++中,默认的复制构造函数用于const引用。 但是,你传入一个const volatile引用;并且默认情况下没有复制构造函数。

您可能会发现将结构的每个成员标记为volatile而不是整个结构更好。

答案 1 :(得分:3)

仅仅因为struct被标记为extern "C"并不意味着它仍然无法编译为C ++代码。

这意味着return mci->info->status;调用隐式生成的复制构造函数。 由于_ARM_MCI_STATUS被标记为volatile,因此它的成员是,这意味着T&的默认复制构造函数无法绑定到它的易失性左值引用中。过去了。

cppreference explanation

中对此进行了解释
  

否则,隐式声明的复制构造函数是T :: T(T&amp;)。 (注意   由于这些规则,隐式声明的复制构造函数   无法绑定到易变的左值参数。

并且在实际标准中(只是很难找到正确的条款,但它在那里)。

答案 2 :(得分:0)

要在KeilμVision5.23中解决此问题,我删除了全局“--cpp”标志。然后我确保所有C ++文件都在项目中的自己的源组中。在该组的选项中,在“C / C ++”选项卡下的“Misc Controls”字段中添加了“--cpp”标志。

通过右键单击项目视图中的文件夹来获取选项。

Options tab for Cpp sources group

目前它编译时没有错误。问题似乎是,如果全局设置了--cpp标志,μVision5.23将编译所有文件c或cpp作为C ++。与Eclipse不同,似乎没有办法为cpp和c文件设置不同的标志。

感谢UKMonkey和Rick Astley。学到了关于volatile和C ++的一些知识。