|
大家好,我是痞子衡,是正經(jīng)搞技術的痞子。今天痞子衡給大家介紹的是MCUXpresso IDE下C++源文件中嵌套定義的復合數(shù)據(jù)類型命名空間認定。
痞子衡之前寫過一篇文章 《MCUXpresso IDE下添加C++源文件進SDK工程編譯的方法》,通過這篇文章我們知道嵌入式工程里是能夠支持 C 源文件和 C++ 源文件混合編譯的(因為有很多開源的庫是基于 C++ 語言的,我們需要移植到嵌入式工程里)。
最近有一個 RW612 客戶在使用官方 SDK 時就遇到一個 C/C++ 混合編譯問題,主要涉及復合數(shù)據(jù)類型(結(jié)構體、聯(lián)合體、枚舉)嵌套定義時的命名空間范圍認定,今天我們就來聊一聊這個話題:
Note1:測試軟件版本為 MCUXpresso IDE v11.10.0_3133Note2:該問題普遍存在于不同 IDE 編譯器,非 GCC 專屬一、引出編譯問題客戶使用得是 SDK_2_16_000_RD-RW612-BGA 開發(fā)包里的基礎 hello_world 例程模板,當客戶嘗試在工程里添加自己創(chuàng)建的 C++ 源文件,并且在該 C++ 源文件中使用 fsl_clock.h 里聲明的如下 clock_frg_clk_config_t 復合數(shù)據(jù)類型時遇到了編譯錯誤:
typedef struct _clock_frg_clk_config
{
uint8_t num;
enum
{
kCLOCK_FrgMainClk = 0,
kCLOCK_FrgPllDiv,
kCLOCK_FrgSFro,
kCLOCK_FrgFFro,
} sfg_clock_src;
uint8_t divider;
uint8_t mult;
} clock_frg_clk_config_t;
客戶出現(xiàn)問題的 C++ 源代碼也足夠簡單,只是定義了 clock_frg_clk_config_t 類型的變量 frg_config,并對其中 sfg_clock_src 成員進行賦值,結(jié)果編譯報錯 'kCLOCK_FrgPllDiv' was not declared in this scope。
clock_frg_clk_config_t frg_config;
frg_config.sfg_clock_src = kCLOCK_FrgPllDiv;
當我們嘗試在 C 源代碼里使用相同的代碼時,編譯是沒問題的,因此可知 clock_frg_clk_config_t 結(jié)構體里直接嵌套的 sfg_clock_src 枚舉類型申明在 C 編譯器(arm-none-eabi-gcc)下命名空間是整個文件,而在 C++ 編譯器(arm-none-eabi-c++)下命名空間僅在 clock_frg_clk_config_t 結(jié)構體內(nèi)。
二、解決編譯問題知道了編譯問題和命名空間有關,要解決問題,那就通過 C++ 的作用域解析運算符 :: 來解決,修改代碼如下,此時編譯正常。但是這樣是完美的解決方案嗎?很顯然,同樣功能的代碼,在 C/C++ 源文件里寫法不一致,這看起來很別扭。
clock_frg_clk_config_t frg_config;
frg_config.sfg_clock_src = clock_frg_clk_config_t::kCLOCK_FrgPllDiv;
什么是更好的解決方案?答案就是單獨申明每個復合數(shù)據(jù)類型原型,讓所有復合數(shù)據(jù)類型命名空間都一樣,這樣我們統(tǒng)一用 C 語言語法即可。實際上在恩智浦官方 SDK 里一直是這樣的設計準則,客戶遇到的這個情況是個“美麗”的意外。
typedef enum _sfg_clock_src
{
kCLOCK_FrgMainClk = 0,
kCLOCK_FrgPllDiv,
kCLOCK_FrgSFro,
kCLOCK_FrgFFro,
} sfg_clock_src_t;
typedef struct _clock_frg_clk_config
{
uint8_t num;
sfg_clock_src_t sfgClockSrc
uint8_t divider;
uint8_t mult;
} clock_frg_clk_config_t;
至此,MCUXpresso IDE下C++源文件中嵌套定義的復合數(shù)據(jù)類型命名空間認定痞子衡便介紹完畢了,掌聲在哪里~~~ |
|