我想做的事情(用于记录目的)是这样的:
这段代码是为了显示我的问题编写的,实际代码很复杂,是的,我有充分的理由在C ++上使用宏=)
# define LIB_SOME 1
# define LIB_OTHER 2
# define WHERE "at file #a, line #l, function #f: "
// (look for syntax hightlighting error at SO xd)
# define LOG_ERROR_SIMPLE(ptr, lib, str) ptr->log ("ERROR " str \
" at library " #lib);
# define LOG_ERROR(ptr, lib, str) LOG_ERROR_SIMPLE(ptr, lib, WHERE str)
LOG_ERROR_SIMPLE (this, LIB_SOME, "doing something")
LOG_ERROR (this, LIB_OTHER, "doing something else")
LOG_ERROR_SIMPLE()
写入lib参数的字符串化(由“”包围的宏名称)
然后LOG_ERROR
写入已扩展的宏的字符串化(“2”)。这是预期的,因为lib在扩展和调用LOG_ERROR_SIMPLE
之前得到了扩展。但这不是我需要的。
基本上我的问题是:在调用另一个宏函数时如何避免宏函数参数的宏扩展?
我使用的一个技巧可以避免宏扩展:
LOG_ERROR(ptr, lib, str, x) LOG_ERROR_SIMPLE(ptr, x##lib, WHERE str)
LOG_ERROR(this, LIB_OTHER, "some error",)
(粘贴x和lib会产生LIB_OTHER
,此值用于调用LOG_ERROR_SIMPLE
,在调用之前不会扩展宏
有一些方法可以在不使用技巧的情况下获得相同的行为吗?
答案 0 :(得分:7)
我在做:
#include <cstdio>
#define FOO 1
#define BAR 2
#define LOG_SIMPLE(ptr, lib, str) printf("%s\n", #lib);
#define LOG(ptr, lib, str) LOG_SIMPLE(ptr, ##lib, str)
int main()
{
LOG_SIMPLE(0, FOO, "some error");
LOG(0, BAR, "some other error");
}
打印出来:
FOO
BAR
适用于MSVC2005 ,但不适用于gcc / g ++ 。
#include <stdio.h>
#define FOO 1
#define BAR 2
#define LOG_SIMPLE(ptr, str, lib) printf("%s\n", #lib);
#define LOG(ptr, str, lib, ...) LOG_SIMPLE(ptr, str, lib##__VA_ARGS__)
int main()
{
LOG_SIMPLE(0, "some error", FOO);
LOG(0, "some other error", BAR);
LOG(0, "some other error", FOO, BAR);
}
但是,不要使用带有太多参数的宏,这是你的纪律。打印出MSVC2005
FOO
BAR
FOO2
而gcc打印出来
FOO
BAR
FOOBAR
答案 1 :(得分:4)
如果你的cpp宏中不需要扩展的lib别名(即'1'和'2'),你也可以使用枚举而不是定义的值。
答案 2 :(得分:0)
我认为你不能。但是,你可以做的是为它添加一层宏来取消它的位置:
#define WRAP(x) x
#define LOG_ERROR(ptr, lib, str) LOG_ERROR_SIMPLE(ptr, lib, WHERE WRAP(str))
答案 3 :(得分:0)
你几乎拥有它。使用
#define LOG_ERROR(ptr, lib, str) LOG_ERROR_SIMPLE(ptr, ##lib, WHERE str)
关于gcc
LOG_ERROR(this, LIB_OTHER, "some error")
产量
this->log ("ERROR " "at file #a, line #l, function #f: " "some error" " at library " "LIB_OTHER");
我也会删除尾随';'从您的宏,以便您的代码看起来像:
LOG_ERROR(this, LIB_OTHER, "some error");