标签: variadic-macros

宏观参数

我有一个系统,其中有许多参数集"macroized"(形式为"#define name value,value,value"的宏).我想将这些宏传递给宏,但是当我这样做时,我得到一个错误.

例:

void fn(int a, int b, int c){ return; }

#define MACRO_1(a, b, c) fn(a, b, c)
#define MACRO(...) MACRO_1(__VA_ARGS__)
#define PARAM1 1
#define PARAM2 2, 2
#define PARAM3 3, 3, 3

int main(int argc, char * argv[]){
   MACRO(0,0,0);
   MACRO(PARAM1,1, 1);
   MACRO(PARAM2,2);
   MACRO(PARAM3);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

在Visual CI中得到:

1>c:\main.c(10): warning C4003: not enough actual parameters for macro 'MACRO_1'
1>c:\main.c(10): error C2059: syntax error : ','
1>c:\main.c(11): warning C4003: not enough actual parameters for macro 'MACRO_1'
1>c:\main.c(11): error …
Run Code Online (Sandbox Code Playgroud)

c macros visual-c++ c-preprocessor variadic-macros

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

如何对包含逗号的字符串进行字符串化?

我想在compile命令中传递一个版本字符串:

$ g++ -Wall -D VERSION="2013-12-03 02:15:21, commit cb060df" -o main main.cpp
Run Code Online (Sandbox Code Playgroud)

在我的代码中,我有以下内容:

#define TOSTR_(x) #x
#define STRINGIFY(x) TOSTR_(x)
#define VERSION_STR STRINGIFY(VERSION)
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为VERSION宏中有一个逗号,所以看起来我传递了两个参数TOSTR()(显然,VERSION宏只有在STRINGIFY()作为一个唯一参数传递后才会被扩展).

我在这里找到的以下方法也不起作用:

#define CONCAT(...) __VA_ARGS__
#define TOSTR_(x) #x
#define STRINGIFY(x) TOSTR_(CONCAT(x))
#define VERSION_STR STRINGIFY(VERSION)
Run Code Online (Sandbox Code Playgroud)

因为这似乎是相同的

#define VERSIONSTR "CONCAT(2013-12-03 02:15:21, commit cb060df)"
Run Code Online (Sandbox Code Playgroud)

也就是说,宏CONCAT()不会扩展.

注1:我宁愿不在命令行中传递一个C字符串,因为版本字符串实际上是动态生成的,它可能包含一些引号.这意味着只写g++ -D VERSION=\""$(GENERATED_STRING)"\"而不是对传递的参数进行字符串化是行不通的.

注2:如果有人在没有任何预处理器宏的情况下找到了这样做的方法,我会非常高兴.

c++ stringification c-preprocessor variadic-macros

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

创建variadic宏/方法,打印所有变量名称和值

现有的宏在我的应用程序中获得可变数量的变量.
我希望,使用此宏,按name=value格式打印这些变量.

这是一个小例子:

#define EXISTING_MACRO(...) < ??? >

int main()
int a = 0;
int b = 1;
int c = 2;

EXISTING_MACRO(a,b,c);
Run Code Online (Sandbox Code Playgroud)

输出应该是:

a=0, b=1, c=2
Run Code Online (Sandbox Code Playgroud)

我已经尝试通过从宏中调用可变参数模板函数来做到这一点,并且我确实成功打印了变量值,但不是变量名称.(#x打印它们的地址,即使它没有,它可能只显示方法变量名称,'f'):

#define SHOW(a) std::cout << #a << "=" << (a)

template<typename TF>
void write_err_output(std::ostream& out, TF const& f) {
    out << f << std::endl;
}

template<typename TF, typename ... TR>
void write_err_output(std::ostream& out, TF const& f, TR const& ... rest) {
    out << SHOW(f) << " "; …
Run Code Online (Sandbox Code Playgroud)

c++ macros variadic-templates variadic-macros

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

可变宏:无法通过“...”传递非平凡可复制类型的对象

我正在尝试为日志记录机制编写一个宏。我写了一个可变参数宏,但它不适用于std::string. 代码如下所示:

#include <stdio.h>
#include <string>


#define LOG_NOTE(m, ...) printf(m, ##__VA_ARGS__)

int main()
{
    std::string foo = "random string";
    int bar = 5;
    LOG_NOTE("%s %d %s", "Hello World", bar, foo);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我像下面这样调用宏,我不会得到任何错误。

LOG_NOTE("%s %d %s", "Hello World", bar, "random string");
Run Code Online (Sandbox Code Playgroud)

编译器输出:

在函数“int main()”中:5:49:错误:无法通过“...”11:5 传递非平凡可复制类型“std::string {aka class std::basic_string}”的对象:注意: 在宏 'LOG_NOTE' 的扩展中

c++ macros variadic-macros

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

用于替换嵌套for循环的宏

我发现这个宏#define TIMES(x) for(int i1=0;i1<x;i1++)非常实用,可以缩短代码文本.但是当我有嵌套循环时,我不知道如何编写这样的宏,甚至我不知道是否可能.这个想法如下.是否可以编写此代码

for(int i1=0;i1<5;i1++)
    for(int i2=0;i2<3;i2++)
        for (int i3=0;i3<7;i3++)
        /* many nested `for` loops */
{
    /* some code, for example to print an array printf("%d \n",a[i1][i2][i3]) */
}
Run Code Online (Sandbox Code Playgroud)

TIMES(5) TIMES(3) TIMES(7) ....
{
    /* some code, for example to print an array printf("%d \n",a[i1][i2][i3]) */
}
Run Code Online (Sandbox Code Playgroud)

用一种"递归"宏来检测所有TIMES并通过for循环替换它们与i1,i2,i3,... i'n'循环计数器?

c macros c-preprocessor variadic-macros

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

争论在宏观中计算

我试图理解C预处理宏中的参数计数和这个答案中的想法.我们有以下宏(为了简单起见,我更改了参数的数量):

#define HAS_ARGS(...) HAS_ARGS_(__VA_ARGS__, 1, 1, 0,)
#define HAS_ARGS_(a, b, c, N, ...) N
Run Code Online (Sandbox Code Playgroud)

据我所知,这个宏的目的是检查给定的varargs是否为空.所以在空的varargs上,宏调用被替换为0似乎很好.但是只有一个参数,它也会变成0,我觉得很奇怪.

HAS_ARGS(); //0
HAS_ARGS(123); //also 0
HAS_ARGS(1, 2); //1
Run Code Online (Sandbox Code Playgroud)

现场演示

我想我明白了原因.如果空的varargs a被替换为空的预处理令牌,则在单个参数的情况下,vararg将被替换为产生相同结果的参数.

有没有办法0在varargs为空的情况下返回,1如果参数号从1到HAS_ARGS_宏调用中的定义,而不使用逗号吞咽或其他不符合的技巧.我的意思是

SOME_MACRO_F() //0
SOME_MACRO_F(234) //1
SOME_MACRO_F(123, 132) //1
//etc
Run Code Online (Sandbox Code Playgroud)

c macros variadic-macros

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

C 中的大小写可变宏

我有 2 个包装宏用于断言函数输入参数:

/**
 * @brief   An assert wrapper with no value return in case assert fails.
 * @param   x_: value to test for being non zero.
 */
#define UTIL_ASSERT_VOID(x_)                                                \
    assert_param(x_);                                                       \
    if (!x_)                                                                \
        return;                                                             \

/**
 * @brief   An assert wrapper with a value return in case assert fails.
 * @param   x_: value to test for being non zero.
 */
#define UTIL_ASSERT_VAL(x_, ret_)                                           \
    assert_param(x_);                                                       \
    if (!x_)                                                                \
        return ret_;                                                        \
Run Code Online (Sandbox Code Playgroud)

前者用于返回 void 的函数,后者用于返回非 void 的函数。我想知道在 …

c macros variadic-macros c11

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

目标C - #define使用__VA_ARGS__

我正在学习如何使用宏但现在与一个混淆.

我正在尝试创建一个NSString将每个params彼此附加的连接.

例如:concatOP(@"hey",@"Jude",@"Don't")将返回一个NSString包含:@"heyJudeDon't"

我实际上做了一些代码(这里也有一些代码)可以得到params的数量,但是我没有成功完成工作的第二部分.

#define NUMARGS(...)        ( sizeof((int[]){__VA_ARGS__}) / sizeof(int) )
#define concatOP(...)       NSMutableString *format = [[NSMutableString alloc] init];\
                            for( int i = 0; i < NUMARGS(__VA_ARGS__); i++){\
                            [format appendString:@"%@"];}\
                            [[NSString alloc] initWithFormat:format, __VA_ARGS__]
Run Code Online (Sandbox Code Playgroud)

我实际上遇到了很多错误,告诉我格式不存在或者我错过了一些";" 或其他结束标签.

objective-c variadic-functions ios c-preprocessor variadic-macros

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

Variadic宏预期')'在数字常量之前

这是实际的宏:

#ifdef DEBUG                                                                   
#define debug(funcname, format, ...) \                                         
        printf(BOLD UNDERLINED REVERSE \                                    
        "DEBUG IN " __FILE__ \                                             
        " LINE " __LINE__ ":" \                                            
        RESET UNDERLINED REVERSE \                                         
        "In " funcname \                                                   
        RESET REVERSE format RESET, ##__VA_ARGS__)                         
#else                                                                          
#define debug(funcname, format, ...)                                           
#endif                                                                        
Run Code Online (Sandbox Code Playgroud)

所有使用的常量都是明确定义的字符串常量.我称之为:

char message[] = "Hello StackOverflow !\n";
debug("main()", "Message: %s\n", message);
Run Code Online (Sandbox Code Playgroud)

但是我收到了消息

error: expected ‘)’ before numeric constant debug("main()", "Message: ", message); 在最后的括号中徘徊.

这很奇怪,因为我第一次测试宏,现在项目已经与团队一起推进它不起作用......

c c-preprocessor variadic-macros

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

三点运算符“...”用于初始化数组

考虑以下使用默认值初始化数组的示例:

static unsigned int array[10] = { [ 0 ... 9 ] = 5 };
Run Code Online (Sandbox Code Playgroud)

这个运算符到底是做什么的?

它与可变参数宏有关__VA_ARGS__

c operators variadic-macros

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