• 可变参数宏


    定义宏时可以让宏接收可变参数,对于可变参数的定义,标准 C 和 GNU C(GNU 对 C的扩展)是不一样的。

    标准 C

    标准 C 对于可变参数的定义如下,使用...:

    #define eprintf(...) fprintf (stderr, __VA_ARGS__)

    在宏定义中,__VA_ARGS__ 代表了所有的可变参数。比如像下面使用宏 eprintf:

    eprintf ("%s:%d: ", input_file, lineno)

    那么 __VA_ARGS__ 就是 "%s:%d: ", input_file, lineno。

    GNU C

    GNU C 除了支持标准 C的定义之外,还有自己的一套定义,同样是定义宏 eprintf,GNU C 中可以定义成:

    #define eprintf(args...) fprintf (stderr, args)

    和标准 C 不同之处在于可变参标志...前面有一个参数名 args,在宏定义里面也没有 __VA_ARGS__,而是直接使用的参数名 args,两者是等价的,但是如果使用 GNU C 的方式,在宏定义中就不可以使用 __VA_ARGS__。

    可变参数为空

    假如定义了如下宏(不管是使用标准 C 方式还是 GNU C方式都可以,这里使用标准 C 的方式):

    #define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)

    在标准 C 的环境下进行如下调用,不传递可变参数:

    eprintf("success!\n");

    宏的扩展将会报错,因为扩展出来后的形式如下:

    fprintf(stderr, "success!\n",);

    fprintf 最后一个参数后面多了一个逗号,这样将报错。这种情况在标准 C 下无法解决,但是 GNU C可以解决。GNU C 赋予 "##" 另一种特殊意义(不是字符串连接的意义了),如果在可变参数前面加上"##",当可变参数为空时,前面的逗号会被删除:

    #define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
    
    // 或者
    #define eprintf(format, args...) fprintf(stderr, format, ##args)

    当可变参数为空时,宏都会扩展成:

    fprintf(stderr, "success!\n");

    可以看到最后一个参数后面的逗号被删除了。

    Clang 默认使用 GNU11,因此也支持这个功能。

  • 相关阅读:
    树莓派AI视觉云台——8、WiringPi库函数
    树莓派AI视觉云台——7、树莓派系统备份
    树莓派AI视觉云台——7、树莓派系统备份
    树莓派AI视觉云台——6、Linux常用命令及vim编辑器的使用
    树莓派AI视觉云台——6、Linux常用命令及vim编辑器的使用
    树莓派AI视觉云台——5.SSH文件传输
    暑假第一周进度报告
    teamfinal使用体验(15号作品)
    《驱动学习
    《驱动学习
  • 原文地址:https://www.cnblogs.com/chaoguo1234/p/16026589.html
Copyright © 2020-2023  润新知