#define和具有可变长度参数的函数

Mic*_*ick 6 c

我在一个庞大的程序中有数以万计的my_printf()函数调用.我现在想要将它们全部转换,以便函数采用一个新的整数参数(称之为x),而不必编辑数以万计的调用.如果my_printf只使用了一个字符串参数,那么我可以这样做:

    #define my_printf(str) _my_printf(x,str)

    void _my_printf(int x,char *str) // changed from my_printf(char *str)
    {
        // stuff
    }
Run Code Online (Sandbox Code Playgroud)

但是由于my_printf采用了可变数量的参数,我不知道该怎么做.可以吗?

编辑:对于那些想知道我为什么要这样做的人,这是一个相关的例子:

#if BELT_AND_BRACES_DIAGNOSTIC_MODE
    #define function(x) _function(__FILE__,__LINE__,x)
#else // speed critical optimised mode
    #define function(x) _function(x)
#endif

#if BELT_AND_BRACES_DIAGNOSTIC_MODE
    void _function(char *file,int line,int x)
#else
    void _function(int x)
#endif
{
    // stuff
    #if BELT_AND_BRACES_DIAGNOSTIC_MODE
    if (something_went_wrong)
    {
        printf("Cock up in function when called from %s line %d\n",file,line);
    }
    #endif
}
Run Code Online (Sandbox Code Playgroud)

phi*_*ant 8

如果代码可以编译为C99代码,则可以定义可变参数宏

#define my_printf(str, args...) _my_printf(x, str, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

预处理器将替换参数...如果仅使用str参数调用宏,GNU预处理器将删除尾随逗号.

  • 这是GNU,而不是C99 - C99版本会读取`define my_printf(str,...)_ my_printf(x,__ VA_ARGS __)`; 请记住,您需要提供一个参数 (2认同)

unw*_*ind 7

最好的事情当然是咬紧牙关并编辑代码.否则你就会创造一个"神秘",需要所有未来的代码维护者来解决.即使那只是你,这正是你会忘记的那种聪明的伎俩.它很难回来,并被奇怪的无意义的宏所困惑.

也就是说,如果你使用的是GNU工具链,你可以考虑使用varargs宏.


Chr*_*oph 7

您可以使用C99可变参数宏:

#define my_printf(...) my_printf_(x, __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

由于Microsoft的实现支持尾随逗号,因此str可以显式添加该参数

#define my_printf(str, ...) my_printf_(x, str, __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

但是,如果在没有可变参数的情况下调用,这将导致标准C中的语法错误

my_printf("foo")
Run Code Online (Sandbox Code Playgroud)

或空参数列表

my_printf("foo",)
Run Code Online (Sandbox Code Playgroud)

因此,我会选择第一个版本.