C multiline macro

C multiline macro

multiline macro

TensorRT/samples/common/common.h中定義了CHECK(status)這個macro:

#define CHECK(status)                                           \
    do                                                          \
    {                                                           \
        auto ret = (status);                                    \
        if (ret != 0)                                           \
        {                                                       \
            std::cerr << "Cuda failure: " << ret << std::endl;  \
            abort();                                            \
        }                                                       \
    } while (0)

以下是在TensorRT/samples/opensource/sampleMNIST/sampleMNIST.cpp中調用該macro的方法:

cudaStream_t stream;
CHECK(cudaStreamCreate(&stream));

我們可以看到在除最後一行外的每行末尾都加上了\\在這裡的作用是line continuition character,即行接續字元(行繼續符),必須有它我們才能跨行定義macro。要注意的是\後面除了\n外什麼都不能加,連也是。

如果沒有加上\,會出現error: expected unqualified-id的錯誤。

從以上代碼可以觀察到的另一個現象是:函數的主要部份外面被包上了do{} while(0)

如果把do{} while(0)拿掉:

#define CHECK(status)                                           \
    auto ret = (status);                                    \
    if (ret != 0)                                           \
    {                                                       \
        std::cerr << "Cuda failure: " << ret << std::endl;  \
        abort();                                            \
    }                                                       \

在編譯時會出現錯誤error: use of undeclared identifier 'ret'

為了避免這個錯誤,需要把{}加回去:

#define CHECK(status)                                           \
	{                                                           \
	    auto ret = (status);                                    \
	    if (ret != 0)                                           \
	    {                                                       \
	        std::cerr << "Cuda failure: " << ret << std::endl;  \
	        abort();                                            \
	    }                                                       \
	}

在這種情況下,如果我們使用CHECK(0);來調用它,那麼這將不會出現任何問題。

但是設想以下這種調用方式:

if(something)
    CHECK(0);
else
    xxx();

以上代碼經過前處理(替換macro)後會變成:

if(something)
{
    auto ret = (status);
    if (ret != 0)
    {
        std::cerr << "Cuda failure: " << ret << std::endl;
        abort();
    }
};
else
    function2();

可以看到,if跟else之間被加入了一個;,這是很明顯的語法錯誤,並將會導致error: expected expression

為了解決這個問題,我們實際上可以把CHECK(0);末尾的;拿掉,但是這樣一來,我們就必須時時刻刻記得哪些是一般的函數,哪些是macro定義的函數,並使用不同的方式來調用它們。

一個比較好的方式是在函數本體外包上do{} while(0),如此一來,CHECK(0);末尾的;就變成必須的,所以不會造成語法錯誤。

參考連結

Why do multi-line macros have backslashes at the end of each line?

Why use do { } while (0) in macro definition? [duplicate]

Multiline macros in C

#define in C with curly braces

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值