用于定义具有可变参数的函数的嵌套#define 问题

Posted

技术标签:

【中文标题】用于定义具有可变参数的函数的嵌套#define 问题【英文标题】:Issue with nested #define for defining a function with variadic arguments 【发布时间】:2021-01-07 00:35:42 【问题描述】:

如何将嵌套的#define 定义到带有可变参数的宏中

#ifndef MY_PRINTF
#define MY_PRINTF(f_, ...)  \
#ifdef USE_WRITE_DEBUG_INFO \
    char buff[200]; \
    sprintf(buff, (f_), __VA_ARGS__); \
    WriteDebugInfo(buff); \
#else \
    printf((f_), __VA_ARGS__); \
#endif \
 
#endif 

Visual Studio 抱怨缺少指令。我会很感激任何提示。

【问题讨论】:

宏不能以产生预处理指令(#ifdef等)的方式展开 【参考方案1】:

定义#define 时不能使用预处理器指令。这意味着您的#ifdef USE_WRITE_DEBUG_INFO 将不起作用。


对于这种情况,使用函数而不是宏:

#include <cstdarg>

void my_printf(const char* format, ...) 
#ifdef USE_WRITE_DEBUG_INFO
    char buff[200];

    va_list args;
    va_start(args, format);
    // Note: uses the snprintf variant rather than sprintf variant,
    // avoiding buffer overlows.
    vsnprintf(buff, 200, format, args);
    va_end(args);

    WriteDebugInfo(buff);
#else
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
#endif


一般来说,您必须将预处理器指令置于 #define 之外:

#ifndef MY_PRINTF

#ifdef USE_WRITE_DEBUG_INFO
// do  ...  while (false) makes the macro behave mostly like a regular function call.
#define MY_PRINTF(f_, ...) do  \
        char buff[200]; \
        sprintf(buff, (f_), __VA_ARGS__); \
        WriteDebugInfo(buff); \
     while (false)
#else
#define MY_PRINTF(f_, ...) printf((f_), __VA_ARGS__)
#endif

#endif 

【讨论】:

你甚至可以使用可变参数模板:template &lt;typename... Ts&gt; void my_printf(const char* format, Ts... args) printf(format, args...); .

以上是关于用于定义具有可变参数的函数的嵌套#define 问题的主要内容,如果未能解决你的问题,请参考以下文章

Python C++ API - 具有可变数量参数的重载函数

Chez Scheme 中的 FFI,用于具有可变参数 (varargs) 的 C 函数

如何在文件系统中找到可变参数宏实现

函数参数函数嵌套作用域名称空间

C语言宏定义实现可变参数

函数