标签: variadic-macros

C预处理器,宏"重载"

我正在尝试做某种宏"重载",以便MACRO(某些东西)的扩展方式与MACRO(其他东西)不同.

使用我从这里得到的片段(我不确定它是否100%便携)和Boost PP库中的一些功能,我能够使它工作:D

//THESE TWO COUNT THE NUMBER OF ARGUMENTS
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)

//THIS ONE RETURNS THE PARAMETER AT POSITION _i FROM A LIST OF __VA_ARGS__
#define VA_ARG(_i, ...) BOOST_PP_ARRAY_ELEM(_i, (VA_NARGS(__VA_ARGS__), (__VA_ARGS__)))

//AND THIS ONE IS THE 'OVERLOADED' MACRO ;)
#define TEST(...) BOOST_PP_IF(BOOST_PP_EQUAL(1, VA_NARGS(__VA_ARGS__)), function_A(VA_ARG(0, __VA_ARGS__)), \ //1 parameter
                  BOOST_PP_IF(BOOST_PP_EQUAL(2, VA_NARGS(__VA_ARGS__)), function_B(VA_ARG(0, __VA_ARGS__) + VA_ARG(1, __VA_ARGS__)), \ //2 parameters
                  BOOST_PP_IF(BOOST_PP_EQUAL(3, VA_NARGS(__VA_ARGS__)), function_C(VA_ARG(1, __VA_ARGS__) + …
Run Code Online (Sandbox Code Playgroud)

macros c-preprocessor variadic-macros boost-preprocessor

4
推荐指数
1
解决办法
5726
查看次数

C语言中可变参数宏的问题

我在C中的#define语句中有可选参数的问题,或者更具体地说是gcc 4.2:

bool func1(bool tmp) { return false; }
void func2(bool tmp, bool tmp2) {}
#define CALL(func, tmp, ...) func(tmp, ##__VA_ARGS__)

int main() {
   // this compiles
   CALL(func2, CALL(func1, false), false);

   // this fails with: Implicit declaration of function 'CALL'
   CALL(func2, false, CALL(func1, false));
}
Run Code Online (Sandbox Code Playgroud)

这显然是一个人为的例子,但确实显示了问题.有谁知道我怎么能得到正确的"解决"的可选参数?


附加信息:如果我删除##之前__VA_ARGS__,并执行以下操作:

bool func2(bool tmp, bool tmp2) { return false; }
#define CALL(func, tmp, ...) func(tmp, __VA_ARGS__)

int main() {
   CALL(func2, false, CALL(func2, false, false));
}
Run Code Online (Sandbox Code Playgroud)

编译,但它不再适用零参数,因为它将解决 func(tmp, ) …

c c-preprocessor variadic-macros

4
推荐指数
1
解决办法
2204
查看次数

具有"占位符"值的宏

我正在使用包含一组预处理器库的库.其中一个是FOR_EACH样式宏,它迭代a __VA_ARGS__并为每个参数调用用户提供的宏.用户提供的宏称为:SOME_MACRO(current_arg)

但是,问题是它只适用于使用单个参数的用户提供的宏.我正在尝试做一些特殊的事情,它涉及struct结构中a 和每个字段的名称.问题是,这需要宏的两个参数.

由于我正在使用的库只接受一元宏,有没有办法将另一个参数"绑定"到我的宏?

截至目前,我必须在宏中硬编码结构的名称.所以,如果struct我正在与之合作Foo,我必须说:

#define MY_MACRO(FIELD) /* do something with &Foo::FIELD */
Run Code Online (Sandbox Code Playgroud)

有没有我可以"绑定"第二个STRUCT参数到宏,也许还有一些间接,所以当库调用我的宏时,它将能够扩展为:

#define MY_MACRO(FIELD) /* do something with &STRUCT::FIELD */
Run Code Online (Sandbox Code Playgroud)

c++ c-preprocessor variadic-macros c++11

4
推荐指数
1
解决办法
860
查看次数

如何将参数传递给可变参数宏?

我有一个可变函数:

LogWrite(FILE * fp, int level, const char * filename, const char * function, ...)
Run Code Online (Sandbox Code Playgroud)

它应该像这样调用:

LogWrite(fp, int Level, __FILE__, __FUNCTION__, "Message: %s", message)
Run Code Online (Sandbox Code Playgroud)

但是,我想编写一个可变参数宏,以便更容易调用:

1: #define LOGWRITE_L1(...) LogWrite(file, 1, __FILE__, __FUNCTION__, ...)
or
2: #define LOGWRITE_L1(file, ...) LogWrite(file, 1, __FILE__, __FUNCTION__, ...)
Run Code Online (Sandbox Code Playgroud)

这样开发人员可以使用以下方法调用它:

LOGWRITE_L1(myfile, "Hello!");
Run Code Online (Sandbox Code Playgroud)

代替

LogWrite(myfile, 1, __FILE__, __FUNCTION__, "Hello!")
Run Code Online (Sandbox Code Playgroud)

但是,这两种方法都给我一个编译器错误.

1: expected expression before '...'
2:'file' undeclared (first use in this function)
Run Code Online (Sandbox Code Playgroud)

这可能还是我在浪费时间?我以前从未使用过变量函数,所以不确定.我的功能工作......我使用完整的声明调用它,并写入我想要的文件.

c macros function variadic-functions variadic-macros

4
推荐指数
1
解决办法
1577
查看次数

避免"ISO C99要求使用休息参数"

使用gcc 4.6.3(带-ansi -pedantic),我有以下代码:

// Argument counting macro
#define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1)
#define NARGS_(_1, _2, _3, _4, _5, _, ...) _

static inline void fi_init_(size_t nargs, fileinfo_t *finfo, ...) {
    // Default fmt/type values
    char* fmt  = "CD";
    int   type = 1000;

    if (nargs == 2) {
        va_list  ap;
        va_start(ap, hdr);
        fmt  = va_arg(ap, char*);
        type = va_arg(ap, int);
        va_end(ap);
    } 

    // Do some junk with it
}

#define fi_init(...) fi_init_(NARGS(__VA_ARGS__)-1, __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

当被称为:

fileinfo_t out; fi_init(&out);
Run Code Online (Sandbox Code Playgroud)

我收到警告: …

c gcc c99 gcc-warning variadic-macros

4
推荐指数
1
解决办法
4457
查看次数

使用__VA_ARGS__转换在MACRO中传递的所有参数

我有一个FOO(...)接收未知数量参数的宏.我想把所有这些参数都用于uint.有没有办法实现它?

c c-preprocessor variadic-macros

4
推荐指数
1
解决办法
2002
查看次数

如何在GNU Make中使用$(call ...)进行可变参数宏

我创建了一个用于makefile的宏:

TODO_MSG = $(warning TODO: $(1))
$(call TODO_MSG, This part of the msg displays fine, but this part does not)
Run Code Online (Sandbox Code Playgroud)

我可以通过以下方式解决这个问题:

BLAH := $(shell perl -e 'print join( " ", 2..200 )'
COMMA := ,
TODO_MSG = $(warning TODO:$(1)$(strip $(foreach x,${BLAH},$(if $(${x}),${COMMA}$(${x}))))
Run Code Online (Sandbox Code Playgroud)

...但我很好奇是否有任何东西可以为变量宏提供更明确的支持.

macros gnu-make variadic-macros

4
推荐指数
1
解决办法
638
查看次数

C预处理器将"int x"拆分为int&x

我需要能够得到以下内容:

#define MY_MACRO(PARAM1,PARAM2) \
 MY_OTHER_MACRO(TYPENAME_OF(PARAM1),PARAMNAME_OF(PARAM1));\
 MY_OTHER_MACRO(TYPENAME_OF(PARAM2),PARAMNAME_OF(PARAM2));\
Run Code Online (Sandbox Code Playgroud)

引起

MY_MACRO(int x,char *z) 
Run Code Online (Sandbox Code Playgroud)

编译为

MY_OTHER_MACRO(int,x);
MY_OTHER_MACRO(char*,z);
Run Code Online (Sandbox Code Playgroud)

如果它编译为:它不会是世界末日:

MY_OTHER_MACRO(int,x);
MY_OTHER_MACRO(char,*z);
Run Code Online (Sandbox Code Playgroud)

或者甚至这也可以:(我可以编码MY_OTHER_MACRO来处理任何一个结果)

MY_OTHER_MACRO(int,x);
MY_OTHER_MACRO(char,z);
Run Code Online (Sandbox Code Playgroud)

或者,如果有一些方法来计算由空格分隔的标记(并假设"*"是单独的标记,我也可以使用它 - 例如2对3)通常,标记用逗号分隔,至我知道.有没有办法使用另一个角色?

c c-preprocessor variadic-macros

4
推荐指数
2
解决办法
2179
查看次数

宏中的__VA_ARGS__是什么意思?

/* Debugging */
#ifdef DEBUG_THRU_UART0
#   define DEBUG(...)  printString (__VA_ARGS__)
#else
void dummyFunc(void);
#   define DEBUG(...)  dummyFunc()   
#endif
Run Code Online (Sandbox Code Playgroud)

我已经在C编程的不同标头中看到了这种表示法,我基本上理解了它在传递参数,但是我不明白这种“三点表示法”是什么意思?

有人可以举例说明它还是提供有关VA Args的链接?

c gcc variadic-functions variadic-macros

4
推荐指数
2
解决办法
1万
查看次数

Visual Studio __VA_ARGS__问题

我运行cl/P test.cpp,文件和结果如下.

TEST.CPP

#define FiltedLog( ...) \
    if (logDetail) \
        MP_LOG(LOG_INFO,  __VA_ARGS__);

#define MP_LOG(level,fmt,...) \
    BOOAT::LOG("MP", level, fmt, ##__VA_ARGS__)

#define LOG(tag,level,fmt,...) \
    Log::log(tag, level, "%s: " fmt, __PRETTY_FUNCTION__, ##__VA_ARGS__)

int main ()
{
     FiltedLog ( "abc", 1, 2);
}
Run Code Online (Sandbox Code Playgroud)

Cl/P test.cpp:

#line 1 "test.cpp"

int main ()
{
     if (logDetail) BOOAT::Log::log("MP", LOG_INFO, "%s: " "abc", 1, 2, __PRETTY_FUNCTION__ );;
}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么__PRETTY_FUNCTION__把它作为结果中的最后一个参数.我假设结果应该是:

 if (logDetail) BOOAT::Log::log("MP", LOG_INFO, "%s: " "abc", __PRETTY_FUNCTION__, 1, 2);;
Run Code Online (Sandbox Code Playgroud)

这是VS 2010的错误吗?

c++ variadic-functions visual-studio-2010 c-preprocessor variadic-macros

3
推荐指数
1
解决办法
1631
查看次数