C volatile 位域结构的复制构造函数
Copy constructor for C volatile bitfield struct
美好的一天
我正在尝试在 C++11 项目中使用 C SD driver/file 系统库 (Keil MDK)。它是由 Pack 管理器在 Keil MDK 5.23 中添加的。我正在使用 ARMCC 5.06u4
进行编译
我收到警告 class "_ARM_MCI_STATUS"
没有合适的复制构造函数”,这很奇怪,因为它声明的 header 有 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 的情况下进行编译,那么它可以正常编译。
有什么建议吗?
在 C++ 中,默认的复制构造函数用于常量引用。
但是,您正在传递一个 const volatile 引用;并且默认情况下没有复制构造函数。
您可能会发现将结构的每个成员标记为易失性比整个结构更好。
仅仅因为您的 struct
被标记为 extern "C"
并不意味着它不会仍然被编译为 C++ 代码。
这意味着return mci->info->status;
调用隐式生成的复制构造函数。
因为 _ARM_MCI_STATUS
被标记为 volatile
,它的成员是,这意味着采用 T&
的默认复制构造函数无法绑定到它传递的易失性左值引用。
这在cppreference explanation中有解释:
Otherwise, the implicitly-declared copy constructor is T::T(T&). (Note
that due to these rules, the implicitly-declared copy constructor
cannot bind to a volatile lvalue argument.)
并且在实际标准中(只是很难找到正确的条款,但它在那里)。
为了解决 Keil µVision 5.23 中的这个问题,我删除了全局“--cpp”标志。然后我确保所有 C++ 文件都在项目中它们自己的源代码组中。在该组的选项中,在 "C/C++" 选项卡下的 "Misc Controls" 字段中添加了“--cpp”标志。
在项目视图中右键单击文件夹可获得选项。
目前编译没有错误。问题似乎是,如果全局设置了 --cpp 标志,µVision 5.23 会将所有文件(c 或 cpp)编译为 C++。与 Eclipse 不同,似乎没有办法为 cpp 和 c 文件设置不同的标志。
感谢 UKMonkey 和 Rick Astley。学习了一些关于 volatile 和 C++ 的知识。
美好的一天
我正在尝试在 C++11 项目中使用 C SD driver/file 系统库 (Keil MDK)。它是由 Pack 管理器在 Keil MDK 5.23 中添加的。我正在使用 ARMCC 5.06u4
进行编译我收到警告 class "_ARM_MCI_STATUS"
没有合适的复制构造函数”,这很奇怪,因为它声明的 header 有 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 的情况下进行编译,那么它可以正常编译。
有什么建议吗?
在 C++ 中,默认的复制构造函数用于常量引用。 但是,您正在传递一个 const volatile 引用;并且默认情况下没有复制构造函数。
您可能会发现将结构的每个成员标记为易失性比整个结构更好。
仅仅因为您的 struct
被标记为 extern "C"
并不意味着它不会仍然被编译为 C++ 代码。
这意味着return mci->info->status;
调用隐式生成的复制构造函数。
因为 _ARM_MCI_STATUS
被标记为 volatile
,它的成员是,这意味着采用 T&
的默认复制构造函数无法绑定到它传递的易失性左值引用。
这在cppreference explanation中有解释:
Otherwise, the implicitly-declared copy constructor is T::T(T&). (Note that due to these rules, the implicitly-declared copy constructor cannot bind to a volatile lvalue argument.)
并且在实际标准中(只是很难找到正确的条款,但它在那里)。
为了解决 Keil µVision 5.23 中的这个问题,我删除了全局“--cpp”标志。然后我确保所有 C++ 文件都在项目中它们自己的源代码组中。在该组的选项中,在 "C/C++" 选项卡下的 "Misc Controls" 字段中添加了“--cpp”标志。
在项目视图中右键单击文件夹可获得选项。
目前编译没有错误。问题似乎是,如果全局设置了 --cpp 标志,µVision 5.23 会将所有文件(c 或 cpp)编译为 C++。与 Eclipse 不同,似乎没有办法为 cpp 和 c 文件设置不同的标志。
感谢 UKMonkey 和 Rick Astley。学习了一些关于 volatile 和 C++ 的知识。