2014-10-19 65 views
8

我用在我的項目一個頭文件有如下定義(一個或多個):是否有任何理由在C中聲明「volatile const」,但在C++中只聲明「volatile」?

#ifdef __cplusplus 
    extern "C" { 
#endif 

#ifdef __cplusplus 
    #define __I  volatile    /*!< Defines 'read only' permissions*/ 
#else 
    #define __I  volatile const  /*!< Defines 'read only' permissions*/ 
#endif 

__I用作另一頭文件如下:

typedef struct { 
    // more members before   
     __I uint32_t CR; /*!< GPIO Commit*/ 
    // more members after 

    } GPIOA_Type; 

#define GPIOF_BASE      0x40025000UL 
#define GPIOF       ((GPIOA_Type *) GPIOF_BASE) 

我的問題是爲什麼會__I在C中被設爲const,但不在C++中?你仍然可以修改CR所指向的值,因爲你有地址,但只是奇怪爲什麼__I的定義是不同的。

對於任何有興趣是什麼,這是對或從 的__I定義是從的IAR Embedded Workbench ARM用於Cortex-M4 和結構是由德州儀器LM4F120H5QR CMSIS文件。

+1

在C++中'const'賦予內部鏈接。我不知道它是否在C中,但我不懷疑。無論如何,請注意'__I'是爲實現保留的名稱,不應在用戶代碼中使用。 – 2014-10-19 21:15:32

+0

@Mat McNabb我的意思是,因爲我有CR寄存器的確切地址,我可以執行以下代碼#define GPIO_PORTF_CR_R(*((volatile unsigned long *)0x40025524)),然後執行GPIO_PORTF_CR_R = xxxxx,並且更改寄存器的值。 – SoftwareDev 2014-10-19 23:49:59

+0

@SoftwareDev OK - 'volatile const CR'表示你不能用'CR'來修改寄存器;當然它可以用其他方式修改 – 2014-10-19 23:53:44

回答

7

在C++中,const文件範圍內的變量默認爲靜態鏈接,這對於內存映射GPIO並不需要。這個「正確」的解決方案是關鍵字extern,但這不能在這裏使用,因爲顯然__I需要與類成員一起工作。因此,根據需要刪除const將使默認鏈接extern

+0

如果這是原因,我還會注意到,無論是誰寫的原代碼可能應該「分叉」'__I'有成員變量的不同版本比全局變量 – 2014-10-19 21:15:42

+0

@MattMcNabb:事後總是20-20。 C++支持可能在宏代碼用於全局變量和成員的C代碼之後很長時間。 – 2014-10-19 21:37:07

+0

@BenVoigt有道理。所以基本上,編寫這段代碼的人說:「即使這是我們想要的,也沒有辦法讓CR只讀在C++中」?雖然我更傾向於寫C代碼的人沒有正確讀數據表,因爲根據它,CR寄存器的值可以從默認值改變,事實上,如果它不能被改變,則無法啓用上拉電阻器在開發板中的一個開關中使用。 – SoftwareDev 2014-10-20 00:08:12