最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在C/C++項目中合理使用宏詳解

 更新時間:2020年12月10日 14:46:48   作者:Duco  
這篇文章主要介紹了在C/C++項目中合理使用宏詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

C++項目中常使用宏來做跨平臺、功能實現(xiàn)隔離、變量定義的功能,這篇文章來討論下是否所有情況下都適合用宏

小D的故事

程序員小D接到一個任務,需要給同事A提供一個復雜公式的實現(xiàn)。輸入為一組參數(shù),輸出一個計算結果。

大致如下:

double computeSomeThing(double paramA,double paramB,double paramC);

小D很快完成了。過了幾天同事A又來找他,說現(xiàn)在需要提升該函數(shù)的性能,建議改為在float類型上,用一些SIMD指令。且同事A表示不是很愿意修改接口。于是小D在考慮以下兩點后決定用一個宏把原來double的實現(xiàn)和float的實現(xiàn)分開來。

1、上層需求變動性比較大,說不定哪天又要用double了。所以還是保留double類型的實現(xiàn)

2、用宏把兩份代碼隔開來,互相不影響比較省事

于是代碼就變成了這樣:

double computeSomeThing(double paramA,double paramB,double paramC)
{
 #ifdef _USE_DOUBLE_
 // do something in double
 #else
 // convert dobule to float 
 // do something in float
 // convert float to double 
 #endif
}

同事A很滿意,因為他只要替換一下.so或.a即可,代碼層不需要改動。于是和小D合作開發(fā)了很多這樣的函數(shù),并且都有float和double兩種實現(xiàn)。在對性能要求高的時候要求小D提供float版本;性能要求低,精度要求的時候要求小D提供double版本。

此時小D會在出庫的時候感到一絲不方便。第一,版本號中需要區(qū)分float和double版本。

第二,因為用宏隔開,切換兩個版本的時候需要重新編譯,而代碼量很多所以編譯時間很長,但這些都是能克服的。

直到有一天同事小B的模塊也需要這個庫,并且小A和小B的模塊要組合起來給小C用,最要命的是小A和小B的模塊分別要用float版本和double版本。所以此時應該提供float版本so還是提供double版本so呢。

問題分析

在上面的場景中,小D作為一個基礎庫的提供者不應該因為同事不愿意修改接口或者圖方便用宏去隔離功能,使得一個接口有了二義性。比較合適的一種做法是,再提供一個控制選擇變量,來選擇用哪種實現(xiàn),即允許運行時決定用float還是double版本。

double computeSomeThing(double paramA,double paramB,double paramC,bool isFast);

或者小A就是不愿意改接口(考慮實際項目中,接口參數(shù)復雜且調(diào)用分散在各處),那么也可以通過增加接口實現(xiàn)。

double computeSomeThing(double paramA,double paramB,double paramC);

void setFast(bool isFast);

下面的情況用宏做隔離就是比較合理的選擇。

比如一套代碼要分別運行在linux和windows上,依賴的頭文件、部分基礎函數(shù)接口都是有區(qū)別的。此時用宏去隔離就比較合理。因為這兩個版本在運行時永遠不會同時出現(xiàn)。除了平臺差異性外,版本管理也可以用宏來做隔離。

比如opencl 1.2和opencl 2.0版本相比較的話,2.0版本中新增了SVM相關的接口。當一個opencl程序未來可能運行在1.2版本的設備和2.0版本的設備上時。

可以用宏來選擇是否屏蔽掉SVM接口。因為2.0的接口運行在1.2的設備上時,無法從環(huán)境中獲取2.0新增的接口實現(xiàn)導致程序跑不起來(1.2的相關so中沒有SVM函數(shù)實現(xiàn))。

不過這個問題用宏來處理也不是最優(yōu)的,使用dlopen可以有更靈活的實現(xiàn)。

總結

對于做基礎庫提供給很多人使用的同學,當用宏隔開的代碼有可能會同時運行在一個環(huán)境時建議改為運行時選擇走哪條分支。但肯定互相不兼容的時候就放心的用宏吧,比如跨操作系統(tǒng)。

另外提一下,對于有很多代碼的大項目用宏的時候也要慎重考慮一下,不要動不動就用宏去做一些功能開關,因為編譯時間太長是很影響效率的。

比如有以下宏定義:

#define _OPEN_LOG_
#ifdef _OPEN_LOG_
 #define LOG_PRINT(...) printf(...)
#else
 #define LOG_PRINT(...) 
#endif

開發(fā)階段代碼中到處插著LOG_PRINT的使用,發(fā)布時關閉打印又是一波整個項目重新編譯。再多來幾個這種功能,每次切換又是整個項目重新編譯,非常煩人??梢杂煤瘮?shù)指針代替:

typedef void (*LogPrint)(const char * pstrMsg);
LogPrint g_LogPrint;
void LogPrint_Imp(const char *pstrMsg)
{
 printf("%s\n",pstrMsg);
 return;
}
void LogPrint_Empty(const char *pstrMsg)
{
 return;
}
int main(int argc,char **argv)
{
 // 此處對日志功能進行開關
 g_LogPrint = LogPrint_Imp ; 
 //g_LogPrint = LogPrint_Empty ; 
 // .....
}
void someFun()
{
 g_LogPrint("in someFun"); //到底打印還是不打印,運行時決定
}

在這個例子中,關閉日志時編譯器只會對main函數(shù)所在的文件進行重新編譯,就不用費時費力的重新編譯整個項目了。而且還可以把g_LogPrint的賦值的行為通過接口開放到上層,由調(diào)用者決定是否需要打開log。

再舉個例子,有些人喜歡項目中各個代碼模塊中用到的參數(shù)提到一個頭文件中,然后各個.c都包含這個頭文件。就像這樣:

// GobalParam.h
#ifndef XX_XX
#define XX_XX
#define DETECTION_MAX 100
#define INPUT_WIDTH_MAX 4096
#define INPUT_HEIGHT_MAX 4096
// 諸如此類很多宏
#endif

我個人覺得下面這種實現(xiàn)更好

// GobalParam.h
#ifndef XX_XX
#define XX_XX
extern const int DETECTION_MAX;
extern const int INPUT_WIDTH_MAX ;
extern const int INPUT_HEIGHT_MAX ;
// 在某個.c或.cpp中賦值 :const int INPUT_HEIGHT_MAX = 100;
#endif

這樣你對某個參數(shù)修改的時候,就不用眼巴巴的等著所有包含此頭文件的編譯模塊重新編譯了。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方歡迎留言討論,望不吝賜教。

相關文章

  • C++內(nèi)存池的簡單實現(xiàn)

    C++內(nèi)存池的簡單實現(xiàn)

    內(nèi)存池是一種動態(tài)內(nèi)存分配與管理技術。本文主要介紹了C++內(nèi)存池的簡單實現(xiàn),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • C++線程池實現(xiàn)代碼

    C++線程池實現(xiàn)代碼

    C++11中,線程我們可以理解為對應一個thread對象,任務可以理解為要執(zhí)行的函數(shù),通常是耗時的函數(shù)。線程過多或者頻繁創(chuàng)建和銷毀線程會帶來調(diào)度開銷,進而影響緩存局部性和整體性能
    2021-12-12
  • C語言 字符串指針詳解及示例代碼

    C語言 字符串指針詳解及示例代碼

    本文主要介紹C語言 字符串指針,這里整理了詳細資料,并附示例代碼及實現(xiàn)結果,有興趣的小伙伴可以參考下
    2016-08-08
  • C語言中字符串庫函數(shù)的實現(xiàn)及模擬

    C語言中字符串庫函數(shù)的實現(xiàn)及模擬

    C語言中有很多數(shù)據(jù)類型,比如int(整數(shù)類型)、char(字符類型)、以及浮點型的double(雙精度)等。但是有一點就是我們發(fā)現(xiàn)這里并沒有提到我們常見的有關字符串的類型。本文為大家介紹了C語言中字符串庫函數(shù)的實現(xiàn)及模擬,需要的可以參考一下
    2022-11-11
  • C++重載的奧義之函數(shù)重載詳解

    C++重載的奧義之函數(shù)重載詳解

    函數(shù)重載是C++多態(tài)(靜態(tài)多態(tài))的特征體現(xiàn),它可以允許重復使用同一個函數(shù)名(籃子)的函數(shù),但是函數(shù)的參數(shù)列表(籃子裝的東西)是可以不一樣的。下面就簡單講講C++中函數(shù)重載的相關應用吧
    2023-04-04
  • C++實現(xiàn)十六進制字符串轉換為十進制整數(shù)的方法

    C++實現(xiàn)十六進制字符串轉換為十進制整數(shù)的方法

    這篇文章主要介紹了C++實現(xiàn)十六進制字符串轉換為十進制整數(shù)的方法,涉及C++字符串與數(shù)制轉換的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • C++算法計時器的實現(xiàn)示例

    C++算法計時器的實現(xiàn)示例

    本文主要介紹了C++算法計時器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • 解析C++無鎖隊列的實現(xiàn)代碼

    解析C++無鎖隊列的實現(xiàn)代碼

    本篇文章是對C++無鎖隊列的實現(xiàn)進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++如何調(diào)用matlab函數(shù)

    C++如何調(diào)用matlab函數(shù)

    這篇文章主要介紹了C++如何調(diào)用matlab函數(shù)的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-11-11
  • C語言多種獲取字符串長度的方法

    C語言多種獲取字符串長度的方法

    這篇文章主要介紹了C語言多種獲取字符串長度的方法,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評論

毕节市| 福建省| 汽车| 桓台县| 都兰县| 镇远县| 赫章县| 呼伦贝尔市| 太康县| 长春市| 吴旗县| 二连浩特市| 潼南县| 天津市| 武义县| 白城市| 治县。| 民乐县| 张家港市| 务川| 桓仁| 敖汉旗| 葫芦岛市| 信宜市| 榕江县| 岐山县| 汉沽区| 承德市| 鄂尔多斯市| 江油市| 古蔺县| 汶川县| 康乐县| 常宁市| 义马市| 云安县| 金阳县| 桐庐县| 富民县| 炎陵县| 舒兰市|