##__VA_ARGS__有什么作用

##__VA_ARGS__ 是 C/C++ 中宏定义(Macro)的一种特殊用法,主要用于可变参数宏(Variadic Macros)的场景,解决当可变参数为空时可能导致的语法错误问题。以下是详细解释:


核心作用

  1. 消除空参数时的多余逗号
    当可变参数部分(__VA_ARGS__)为空时,##__VA_ARGS__ 会自动移除其前面的逗号,避免因多余逗号导致编译错误。
    如果可变参数非空,则正常展开参数。

    // 定义宏时使用 ##__VA_ARGS__
    #define LOG(format, ...) printf(format, ##__VA_ARGS__)
    
    • 调用示例 1LOG("Hello");
      展开后:printf("Hello")
      (没有可变参数时,## 移除了 printf(format, ) 中的逗号)

    • 调用示例 2LOG("Hello %s", "World");
      展开后:printf("Hello %s", "World")
      (有可变参数时,正常展开)

  2. 兼容不同参数数量的场景
    让宏能同时支持以下两种调用方式:

    • 带可变参数:LOG("Value: %d", 42);
    • 不带可变参数:LOG("Simple message");

对比普通 __VA_ARGS__

若直接使用 __VA_ARGS__,当可变参数为空时,宏展开后会产生多余的逗号,导致语法错误:

#define BAD_LOG(format, ...) printf(format, __VA_ARGS__)BAD_LOG("Hello"); // 展开为 printf("Hello", ) → 语法错误!

##__VA_ARGS__ 会智能处理空参数,避免此问题。


注意事项

  1. 编译器兼容性
    ##__VA_ARGS__GNU 扩展语法(如 GCC、Clang 支持),但并非 C/C++ 标准的一部分。在严格遵循标准的编译器(如 MSVC 的某些模式)中可能无法使用。

  2. C++20 的替代方案
    C++20 引入了 __VA_OPT__ 作为标准替代方案,可更灵活地处理空参数:

    #define LOG(format, ...) printf(format __VA_OPT__(, ) __VA_ARGS__)
    
  3. 参数顺序限制
    ##__VA_ARGS__ 必须放在宏参数列表的最后,且只能用于可变参数部分。


典型应用场景

  • 日志函数DEBUG_LOG("Error: %s", err_msg);DEBUG_LOG("Connection closed");
  • 调试宏ASSERT(ptr != NULL, "Pointer is null");
  • 泛型代码生成:根据参数数量动态生成代码。

总结

##__VA_ARGS__ 的核心价值是让可变参数宏在参数为空时仍能正确展开,避免语法错误。它是 GNU 编译器的实用扩展,但需注意跨平台兼容性。在 C++20 中,建议优先使用 __VA_OPT__ 替代。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14692.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言【基础篇】之数组——解锁多维与动态数组的编程奥秘

数组 🚀前言🦜数组的由来与用途🌟一维数组详解🖊️二维数组进阶💯动态数组原理🤔常见误区扫盲💻学习路径建议✍️总结 🚀前言 大家好!我是 EnigmaCoder。本文收录于我的专…

TaskBuilder项目实战:创建项目

用TaskBuilder开发应用系统的第一步就是创建项目,项目可以是一个简单的功能模块,也可以是很多功能模块的集合,具体怎么划分看各位的实际需要,我们一般会将相互关联比较紧密的一组功能模块放到一个独立的项目内,以便打包…

基于DeepSeek API和VSCode的自动化网页生成流程

1.创建API key 访问官网DeepSeek ,点击API开放平台。 在开放平台界面左侧点击API keys,进入API keys管理界面,点击创建API key按钮创建API key,名称自定义。 2.下载并安装配置编辑器VSCode 官网Visual Studio Code - Code Editing…

Redis深入学习

目录 Redis是什么? Redis使用场景 Redis线程模型 Redis执行命令是单线程的为什么还这么快? Redis持久化 Redis 事务 Key 过期策略 Redis 和 mysql 如何保证数据一致? 缓存穿透 缓存击穿 缓存雪崩 Redis是什么? redis是一…

Dockerfile 文件详解

在平常的开发工作中,我们经常需要部署项目,一个项目开发完成后,使用 Docker 方式部署,那么首先得构造镜像,构造镜像最主要的就是 Dockerfile 文件的编写,今天简单来总结下 Dockerfile 文件的编写以及有哪些…

开源模型应用落地-CodeQwen模型小试-SQL专家测试(二)

一、前言 代码专家模型是基于人工智能的先进技术,它能够自动分析和理解大量的代码库,并从中学习常见的编码模式和最佳实践。这种模型可以提供准确而高效的代码建议,帮助开发人员在编写代码时避免常见的错误和陷阱。 通过学习代码专家模型&a…

kubeadm构建k8s源码阅读环境

目标 前面看了minikube的源码了解到其本质是调用了kubeadm来启动k8s集群,并没有达到最初看代码的目的。 所以继续看看kubeadm的代码,看看能否用来方便地构建源码调试环境。 k8s源码编译 kubeadm源码在k8s源码库中,所以要先克隆k8s源码。之…

LLM学习笔记1——本地部署Meta-Llama-3.2-1B大模型

系列文章目录 参考博客 参考博客 文章目录 系列文章目录前言与调用一、部署要求二、实现步骤0.深度学习环境错误1,验证pytorch版本时提示以下问题:错误2,验证pytorch版本时提示以下问题:错误3,有时候还会提示你有一些…

搜维尔科技:提供人形机器人传感器的应用案例分析

视觉传感器 • 家庭服务场景:在家庭清洁机器人中,视觉传感器可以识别家具、障碍物的位置和形状,规划清洁路径,避开桌椅、宠物玩具等。如小米扫地机器人,通过视觉传感器与算法结合,能构建房间地图&#xff…

windows蓝牙驱动开发-蓝牙 LE 邻近感应配置文件

邻近感应检测是蓝牙低功耗 (LE) 的常见用途。 本部分提供了创建可用于开发 UWP 设备应用的邻近感应配置文件的设备实现的指南。 在开发此应用之前,应熟悉蓝牙 LE 函数和蓝牙 LE 邻近感应配置文件规范。 示例服务声明 蓝牙低功耗引入了一个新的物理层,…

逻辑回归:Sigmoid函数在分类问题中的应用

欢迎来到我的主页:【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 什么是Sigmoid函数? Sigmoid函数(Logistic函数)是机器学习中最经典的激活函数之一,是一个在生物学中常见的S型函数,也称为S型生长曲线。…

如何在Windows中配置MySQL?

MySQL是一个广泛使用的开源关系型数据库管理系统,它支持多种操作系统平台,其中包括Windows。无论是开发者进行本地开发,还是管理员为应用程序配置数据库,MySQL都是一个非常流行的选择。本篇文章将详细介绍如何在Windows操作系统中…

MySQL的操作

一.数据库的操作 1.创建数据库 create database (if not exists) 数据库名称 (character set/charset 字符集名称); SQL中有特定含义的单词(create database)也就是关键字 在创建数据库名 表名 列名的时候都可以和关键字重复 。 if not exists&#xff1…

MariaDB *MaxScale*实现mysql8读写分离

1.MaxScale 是干什么的? MaxScale是maridb开发的一个mysql数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换,对多个从服务器能实现负载均衡。 2.MaxScale 实验环境 中间件192.168.12…

响应式编程_05 Project Reactor 框架

文章目录 概述响应式流的主流实现框架RxJavaReactor Project Reactor 框架Reactor 异步数据序列Flux 和 Mono 组件FluxMono 操作符背压处理 小结 概述 响应式编程_02基本概念:背压机制 Backpressure介绍了响应式流规范以及 Spring 框架中的响应式编程技术&#xff…

免费windows pdf编辑工具Epdf

Epdf(完全免费) 作者:不染心 时间:2025/2/6 Github: https://github.com/dog-tired/Epdf Epdf Epdf 是一款使用 Rust 编写的 PDF 编辑器,目前仍在开发中。它提供了一系列实用的命令行选项,方便用户对 PDF …

计算机组成原理(3)

计算机组成原理(3) 存储器层次结构存储器概述存储器分类存储器性能指标 半导体随机存储SRAM和DRAM 存储器层次结构 主存-辅存:实现了虚拟存储系统,解决了主存容量不足的问题; Cache-主存:解决了主存于CPU速…

html 列动态布局

样式说明: /* 列动态布局,列之间以空格填充 */ li {display: flex;/* flex-direction: column; */justify-content: space-between; }

25/2/8 <机器人基础> 阻抗控制

1. 什么是阻抗控制? 阻抗控制旨在通过调节机器人与环境的相互作用,控制其动态行为。阻抗可以理解为一个力和位移之间的关系,涉及力、速度和位置的协同控制。 2. 阻抗控制的基本概念 力控制:根据感测的外力调节机械手的动作。位置…

Redis03 - 高可用

Redis高可用 文章目录 Redis高可用一:主从复制 & 读写分离1:主从复制的作用2:主从复制原理2.1:全量复制2.2:增量复制(环形缓冲区) 3:主从复制实际演示3.1:基本流程准…