我有一个系统,其中有许多参数集"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) 我想在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:如果有人在没有任何预处理器宏的情况下找到了这样做的方法,我会非常高兴.
现有的宏在我的应用程序中获得可变数量的变量.
我希望,使用此宏,按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) 我正在尝试为日志记录机制编写一个宏。我写了一个可变参数宏,但它不适用于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' 的扩展中
我发现这个宏#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预处理宏中的参数计数和这个答案中的想法.我们有以下宏(为了简单起见,我更改了参数的数量):
#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) 我有 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 的函数。我想知道在 …
我正在学习如何使用宏但现在与一个混淆.
我正在尝试创建一个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
这是实际的宏:
#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); 在最后的括号中徘徊.
这很奇怪,因为我第一次测试宏,现在项目已经与团队一起推进它不起作用......
考虑以下使用默认值初始化数组的示例:
static unsigned int array[10] = { [ 0 ... 9 ] = 5 };
Run Code Online (Sandbox Code Playgroud)
这个运算符到底是做什么的?
它与可变参数宏有关__VA_ARGS__?
variadic-macros ×10
c ×6
macros ×6
c++ ×3
c11 ×1
ios ×1
objective-c ×1
operators ×1
visual-c++ ×1