C/C++ 宏操作小技巧

Abstract

之前写了一个非常mini的log库(也不算库把,自己瞎jb写的),里面几乎都是宏的实现。这里打算趁热打铁,把自己知道的几下子都贴出来,后续如果有新的收获会更新这个博文。

文笔拙劣,主要是给自己做个提醒。

运行时检测大小端

一目了然,不做解释。

#define is_big_endian() ({short _a = 0x1234;*((char *)&_a) == 0x12; })
#define is_little_endian() ({short _a = 0x1234;*((char *)&_a) == 0x34; })

当然还有另一种方式去确定字节序。下面是编译时确定字节序的方式。

只要通过引入头文件 <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

max函数与min函数

max与min函数是最常用的。我们可以有很多方式去实现它,宏,inline,函数等。
由于这两个函数都很小,一般用宏最简单。

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

SDK 中的函数名拼接

#define test(__VER, args) __SDK_##__VER##_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;
}

版本号

#define _STRINGFY(v) #v
#define STRINGFY(v) _STRINGFY(v)

#define MAJOR 1
#define MINOR 2
#define REVISION 3
#define VERSION_CODE \
    STRINGFY(MAJOR)  \
    "." STRINGFY(MINOR) "." STRINGFY(REVISION)

这样直接暴露一个 VERSION_CODE 的版本号。
看起来好像没什么用,直接用一个字符串不是更好???那么每次修改版本都要修改代码岂不是很烦!!!所以我们能在编译时候,以参数形式提供版本参数,那么更灵活。

获取枚举变量的名字

枚举定义通常具有更好的可读性, 比如

enum enWeek_t {MONDAY, TUESDAY};

中MONDAY与TUSDAY比枚举值 0,1 有更好的可读性。事实上对于开发者,一个可读性更好的名称比这个名称的实际值加友好。如果是日志上能给出 ‘MONDAY’ 而不是 0这样的字眼,更能帮助我们理解。所以获取枚举类型的名称或许是个更好的选择。

一个示例:

// enum_name.h
#ifndef __ENUM_NAME_H__
#define __ENUM_NAME_H__

#define WEEKDAYS          \
    MACRO_HELPER(MONDAY)  \
    MACRO_HELPER(TUESDAY) \
    MACRO_HELPER(WEDNESDAY)

#define MACRO_HELPER(v) v,
enum
{
    WEEKDAYS
};
#undef MACRO_HELPER

#define STRINGFY(v) #v
#define MACRO_HELPER(v) STRINGFY(v),
static const char *weekdays[] = {WEEKDAYS};
#undef MACRO_HELPER

#endif //__ENUM_NAME_H__
}

怎么使用呢?很简单 weekdays[MONDAY] 这么用就行。。。

posted @ 2019-04-28 18:10  sinpo828  阅读(483)  评论(0编辑  收藏  举报