You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改C语言可变参数宏print()以支持无参数传入不报错?

解决C语言print宏处理空参数的问题

问题根源

调用print()无参数时,原宏中的int array[] = {__VA_ARGS__}会展开为int array[] = {},这不符合C标准(C不允许自动存储期的数组空初始化),直接触发编译错误;同时空__VA_ARGS__会导致宏展开语法异常。

修改方案

利用C11标准的_Generic特性与宏粘贴运算符##,区分有无参数的场景,避免空数组初始化问题:

修改后的完整代码

#include <stdio.h>
#include <stdarg.h>

void function_for_printing(int len, ...)
{
    va_list args;
    va_start(args, len);
    if (len > 0)
    {
        for (int i = 0; i < len; i++)
        {
            int temp = va_arg(args, int);
            printf("%d ", temp);
        }
        printf("\n");
    }
    else
    {
        printf("Nothing passed\n");
    }
    va_end(args);
    printf("\n");
}

// 辅助宏:处理有参数的情况
#define _PRINT_HAS_ARGS(...) \
    do { \
        int array[] = {__VA_ARGS__}; \
        int size = sizeof(array)/sizeof(array[0]); \
        function_for_printing(size, __VA_ARGS__); \
    } while(0)

// 辅助宏:处理空参数的情况
#define _PRINT_NO_ARGS() \
    function_for_printing(0)

// 核心宏:通过类型匹配区分有无参数
#define print(...) \
    _Generic((int[]){0, ##__VA_ARGS__}, \
        int[1]: _PRINT_NO_ARGS(), \
        default: _PRINT_HAS_ARGS(__VA_ARGS__))

int main()
{
    print(1, 2, 4); // 正常打印参数
    print(1, 2, 3, 4, 5, 6, 7); // 正常打印参数
    print(); // 正确输出"Nothing passed"

    return 0;
}

代码说明

  1. _Generic类型匹配:
    • 无参数时,(int[]){0, ##__VA_ARGS__}展开为(int[]){0},类型为int[1],匹配_PRINT_NO_ARGS分支;
    • 有参数时,展开为(int[]){0, arg1, arg2,...},类型为int[N](N>1),匹配_PRINT_HAS_ARGS分支。
  2. ##__VA_ARGS__的作用:当__VA_ARGS__为空时,##会删除前面的逗号,避免出现(int[]){0,}的语法错误。
  3. do-while(0)包裹宏:确保宏在任何上下文(如if语句后)都能正确展开,避免语法冲突。
  4. 修复原函数的未定义行为:将va_end(args)移至函数末尾统一调用,保证va_start与va_end成对出现。

简化方案(GCC专属)

若使用GCC编译器,可利用C23标准的__VA_OPT__扩展简化代码:

#define print(...) \
    do { \
        int array[] = {0 __VA_OPT__(,) __VA_ARGS__}; \
        int size = sizeof(array)/sizeof(int) - 1; \
        function_for_printing(size, __VA_OPT__(__VA_ARGS__, 0)); \
    } while(0)

__VA_OPT__(,) __VA_ARGS__会在有参数时插入逗号分隔参数,无参数时为空;size通过数组总长度减1得到实际参数个数。

内容的提问来源于stack exchange,提问作者Sakib Khandaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:30:08