使用C語言的宏來解決一個(gè)問題

宏因?yàn)槠涓鞣N副作用而備受詬病,就像goto一樣,有些產(chǎn)品談宏色變。但是語言特性本身并無善惡之分,其善惡在于使用者。有時(shí)候使用某些語言特性,能夠非常好的解決一些編程中的難題。本文就使用宏來解決一個(gè)比較棘手的問題。
有一個(gè)函數(shù),原型如下:

// a.h
void TEST(unsigned int a, unsigned int b, unsigned int c);

在UT測試中,要對這個(gè)函數(shù)打樁,打樁成了一個(gè)宏,實(shí)現(xiàn)如下:

// b.h
#define TEST(a, b, c)  a = b + c

在main函數(shù)中如下調(diào)用:

// mian.c
int main()
{
    int a = 5, b = 3, c = 8;
    TEST(a, b, c);
    return 0;
}

在編譯時(shí),會(huì)根據(jù)是否是UT工程決定使用a.h還是b.h。

當(dāng)使用a.h時(shí)會(huì)有一個(gè)告警,因?yàn)?code>TEST函數(shù)的定義形參要求是unsigned int,而實(shí)參是int。因?yàn)槭褂?code>TEST的地方很多,且情況比較復(fù)雜,只能使用類型強(qiáng)轉(zhuǎn)清除這個(gè)告警。
改成如下形式,UT工程編譯不過(原因是宏展開后,等式的左值不能有強(qiáng)轉(zhuǎn))

// mian.c
int main()
{
    int a = 5, b = 3, c = 8;
    TEST((unsigned int)a, (unsigned int)b, (unsigned int)c);
    return 0;
}

怎么辦?
好像沒有什么好辦法,試著將TEST重定義,如下:

#ifdef _UT_
#define MY_TEST(a, b, c)  TEST(a, b, c)
#else
#define MY_TEST(a, b, c)  TEST((unsigned int)a, (unsigned int)b, (unsigned int)c)
#endif

int main()
{
    int a = 5, b = 3, c = 8;
    MY_TEST(a, b, c);
    return 0;
}

問題看似解決,但是伴隨的是成千上萬出的TEST調(diào)用要換成MY_TEST的調(diào)用,并且后續(xù)開發(fā)人員必須要遵守使用MY_TEST的規(guī)則,否則就會(huì)出錯(cuò)。

有沒有更好的辦法,使得影響降至最小?仔細(xì)想下,UT工程并不關(guān)心數(shù)據(jù)類型的轉(zhuǎn)換,如果能夠?qū)㈩愋娃D(zhuǎn)換那一部分((unsigned int))在宏展開時(shí)替換掉就能解決問題。
如果能夠讓(unsigned int)前面拼接一個(gè)符號(hào)組成一個(gè)宏函數(shù),然后定義這個(gè)宏函數(shù)的實(shí)現(xiàn)為空即可,如下:

#define DUMMY(...)
#define TEST(a, b, c)  DUMMY#a = DUMMY#b + DUMMY#c

對于TEST((unsigned int)a, (unsigned int)b, (unsigned int)c);期望展開后是DUMMY(unsigned int)a = DUMMY(unsigned int)b + DUMMY(unsigned int)c,DUMMY(unsigned int)為空,則替換后為a = b + c,完美。

但是,上面的做法是錯(cuò)的,編譯不過,因?yàn)槭褂?code>#展開后的形式是DUMMY"(unsigned int)a" = DUMMY"(unsigned int)b" + DUMMY"(unsigned int)c"。
正確的寫法是去掉#,但一定要在DUMMY和宏參數(shù)間加上空格,如下:

#define DUMMY(...)
#define TEST(a, b, c)  DUMMY a = DUMMY b + DUMMY c

至此,使用宏完美地解決了這個(gè)看似無解的問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容