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

在C/C++項(xiàng)目中合理使用宏詳解

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

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

小D的故事

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

大致如下:

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

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

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

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

于是代碼就變成了這樣:

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很滿意,因?yàn)樗灰鎿Q一下.so或.a即可,代碼層不需要改動(dòng)。于是和小D合作開發(fā)了很多這樣的函數(shù),并且都有float和double兩種實(shí)現(xiàn)。在對(duì)性能要求高的時(shí)候要求小D提供float版本;性能要求低,精度要求的時(shí)候要求小D提供double版本。

此時(shí)小D會(huì)在出庫(kù)的時(shí)候感到一絲不方便。第一,版本號(hào)中需要區(qū)分float和double版本。

第二,因?yàn)橛煤旮糸_,切換兩個(gè)版本的時(shí)候需要重新編譯,而代碼量很多所以編譯時(shí)間很長(zhǎng),但這些都是能克服的。

直到有一天同事小B的模塊也需要這個(gè)庫(kù),并且小A和小B的模塊要組合起來(lái)給小C用,最要命的是小A和小B的模塊分別要用float版本和double版本。所以此時(shí)應(yīng)該提供float版本so還是提供double版本so呢。

問(wèn)題分析

在上面的場(chǎng)景中,小D作為一個(gè)基礎(chǔ)庫(kù)的提供者不應(yīng)該因?yàn)橥虏辉敢庑薷慕涌诨蛘邎D方便用宏去隔離功能,使得一個(gè)接口有了二義性。比較合適的一種做法是,再提供一個(gè)控制選擇變量,來(lái)選擇用哪種實(shí)現(xiàn),即允許運(yùn)行時(shí)決定用float還是double版本。

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

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

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

void setFast(bool isFast);

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

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

比如opencl 1.2和opencl 2.0版本相比較的話,2.0版本中新增了SVM相關(guān)的接口。當(dāng)一個(gè)opencl程序未來(lái)可能運(yùn)行在1.2版本的設(shè)備和2.0版本的設(shè)備上時(shí)。

可以用宏來(lái)選擇是否屏蔽掉SVM接口。因?yàn)?.0的接口運(yùn)行在1.2的設(shè)備上時(shí),無(wú)法從環(huán)境中獲取2.0新增的接口實(shí)現(xiàn)導(dǎo)致程序跑不起來(lái)(1.2的相關(guān)so中沒(méi)有SVM函數(shù)實(shí)現(xiàn))。

不過(guò)這個(gè)問(wèn)題用宏來(lái)處理也不是最優(yōu)的,使用dlopen可以有更靈活的實(shí)現(xiàn)。

總結(jié)

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

另外提一下,對(duì)于有很多代碼的大項(xiàng)目用宏的時(shí)候也要慎重考慮一下,不要?jiǎng)硬粍?dòng)就用宏去做一些功能開關(guān),因?yàn)榫幾g時(shí)間太長(zhǎng)是很影響效率的。

比如有以下宏定義:

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

開發(fā)階段代碼中到處插著LOG_PRINT的使用,發(fā)布時(shí)關(guān)閉打印又是一波整個(gè)項(xiàng)目重新編譯。再多來(lái)幾個(gè)這種功能,每次切換又是整個(gè)項(xiàng)目重新編譯,非常煩人??梢杂煤瘮?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)
{
 // 此處對(duì)日志功能進(jìn)行開關(guān)
 g_LogPrint = LogPrint_Imp ; 
 //g_LogPrint = LogPrint_Empty ; 
 // .....
}
void someFun()
{
 g_LogPrint("in someFun"); //到底打印還是不打印,運(yùn)行時(shí)決定
}

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

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

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

我個(gè)人覺(jué)得下面這種實(shí)現(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 ;
// 在某個(gè).c或.cpp中賦值 :const int INPUT_HEIGHT_MAX = 100;
#endif

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

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

相關(guān)文章

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

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

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

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

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

    C語(yǔ)言 字符串指針詳解及示例代碼

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

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

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

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

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

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

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

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

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

    解析C++無(wú)鎖隊(duì)列的實(shí)現(xiàn)代碼

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

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

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

    C語(yǔ)言多種獲取字符串長(zhǎng)度的方法

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

最新評(píng)論

织金县| 江源县| 韶山市| 蓬莱市| 龙游县| 墨江| 宜宾市| 许昌市| 青河县| 台湾省| 南平市| 扎鲁特旗| 望都县| 安福县| 岱山县| 本溪市| 奈曼旗| 定西市| 德清县| 冀州市| 秭归县| 古丈县| 吉木乃县| 南投县| 平潭县| 溆浦县| 连山| 米泉市| 瓦房店市| 黔南| 建平县| 贵港市| 五华县| 尼勒克县| 芒康县| 璧山县| 宜州市| 章丘市| 鲜城| 雅安市| 南京市|