1. 程式人生 > >C/C++ 宏操作小技巧

C/C++ 宏操作小技巧

參考 提醒 文件 clu brush 收獲 rgs stdout 解釋

Abstract

之前寫了一個非常mini的log庫(也不算庫把,自己瞎jb寫的),裏面幾乎都是宏的實現。這裏打算趁熱打鐵,把自己知道的幾下子都貼出來,後續如果有新的收獲會更新這個博文。

文筆拙劣,主要是給自己做個提醒。

1. 運行時檢測大小端

一目了然,不做解釋。

#define __ENDIAN() ({         short _a = 0x1234;         *((char*)&_a) == 0x12 ? 1 : 0;     })
#define big_endian()  (__ENDIAN() == 1)
#define little_endian()  (__ENDIAN() == 0)

當然還有另一種方式去確定字節序。下面是編譯時確定字節序的方式。

只要通過引入頭文件<endian.h>便可以在編譯時通過宏判斷字節序了。參考 ‘/usr/include/linux/tcp.h’ 你會發現另一種寫法(自己去看下)。

#if __BYTE_ORDER == __LITTLE_ENDIAN
    // do_sth();
#elif __BYTE_ORDER == __BIG_ENDIAN
    // do_sth();
#else
#error "Unknown byte order"
#endif

2. max函數與min函數

max與min函數是最常用的。我們可以有很多方式去實現它,宏,inline,函數等。

由於這兩個函數都很小,一般不建議

#define max(a, b) ({         typeof(a) _a = a;         typeof(b) _b = b;         _a >= _b ? _a : _b;     })

3. SDK 中的函數名拼接

#include <stdio.h>

#define test(__DOC, args) __SDK_##__DOC##_TEST(args)
void __SDK_V1_TEST(int a) {
    fprintf (stdout, "version %d\n", a);
    return;
}

void __SDK_V2_TEST(int a) {
    fprintf (stdout, "version %d\n", a);
    return;
}

int main(int argc, char **argv) {
    test(V1, 1);
    test(V2, 2);
    return 0;
}

C/C++ 宏操作小技巧