2017-07-25 48 views
2

好日子复制构造对于C挥发性位域结构

我试图使用C SD驱动程序/文件系统libary(凯尔MDK),在C++ 11的项目。 Keil MDK 5.23中的Pack Manager增加了它。我与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; 

当该结构是为发生该问题[R在eturned:

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

status被声明为ARM_MCI_STATUS status;。我不明白为什么它应该是一个问题。

如果我编译没有--cpp,那么它编译没有问题。

有什么建议吗?

+3

仅仅因为它被标记为'extern“C”并不意味着它绕过了C++规则。 –

+2

结构和类型名称永远不需要'extern“C”',只有函数可以。它所做的基本上是防止函数的[name-mangling](https://en.wikipedia.org/wiki/Name_mangling)。 –

+0

@RickAstley我正在收集,虽然我是/不知道一个特定的C++规则需要一个基本的C位字段的复制构造函数。你知道吗? – Flip

回答

3

仅仅因为您的struct标记为extern "C"并不意味着它仍不会被编译为C++代码。

这意味着return mci->info->status;调用隐式生成的复制构造函数。 由于_ARM_MCI_STATUS标记为volatile,它是成员,这意味着需要T&的默认拷贝构造函数不能绑定到它传递的易变的左值引用。

这在cppreference explanation解释:

否则,隐式声明的拷贝构造函数是T :: T(牛逼&)。 (注意 ,由于这些规则,隐式声明的拷贝构造函数 不能绑定到挥发性左值的论点。

而且还实际标准(只要有一个很难找到正确的条款,但它在那里)。

3

在C++中,默认的拷贝构造函数用于const引用。 但是,你传入一个const volatile参考;并没有复制构造函数默认为此。

您可能会发现将结构的每个成员标记为易失性而非整个结构会更好。

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++的知识。