2017-07-25 73 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++的知識。