CPP:避免宏函数参数的宏扩展
我想做的(出于日志记录的目的)是这样的:
编写此代码是为了显示我的问题,实际代码很复杂,是的,我有充分的理由即使在 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
,它在该调用之前没有宏扩展)
有某种方法可以在不使用技巧的情况下获得相同的行为吗?
what I'd like to do (for logging purposes) is something like this:
This code has been written to show my problem, actual code is complex and yes, I have good reasons to use macros even on 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()
writes the stringification of the lib parameter (a macro name surrounded by " ")
but then LOG_ERROR
writes the stringification of the macro already expanded ("2"). this is expected, since lib got its expansion before expanding and calling LOG_ERROR_SIMPLE
. but this is not what I need.
Basically my question is this: how to avoid macro expansion of a macro function parameter when calling another macro function?
There is a trick I use that avoids macro expansion:
LOG_ERROR(ptr, lib, str, x) LOG_ERROR_SIMPLE(ptr, x##lib, WHERE str)
LOG_ERROR(this, LIB_OTHER, "some error",)
(pasting x and lib produces LIB_OTHER
and this value is used to call LOG_ERROR_SIMPLE
, its not macro expanded before that call)
There is some way to obtain this same behaviour without using a trick?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我正在做:
打印出:
Works with MSVC2005 but not with gcc/g++.
编辑:要使其与 gcc/g++ 一起使用,您可以滥用可变参数宏:
但是,您的纪律是不要使用带有太多参数的宏。 MSVC2005 打印出来
,而 gcc 打印出来
I'm doing:
which prints out:
Works with MSVC2005 but not with gcc/g++.
EDIT: to make it work with gcc/g++ you can abuse variadic macros:
However, it's your discipline not to use the macro with too many parameters. MSVC2005 prints out
while gcc prints out
如果您的 cpp 宏中不需要扩展的库别名(即“1”和“2”),您也可以使用枚举而不是定义的值。
If you don't need the expanded lib aliases (i.e. '1' & '2') in your cpp macros, you could also use an enum instead of defined values.
我认为你不能。不过,您可以做的是添加一层宏以使其在其位置上剥落:
I don't think you can. What you could do, though, is add a layer of macro for it to unpeel in its place:
你几乎已经拥有了。 使用
在 gcc 上
LOG_ERROR(此,LIB_OTHER,“一些错误”)
产量
this->log ("ERROR " "at file #a, line #l, function #f: " "some error" " at library " "LIB_OTHER");
我也会删除尾随';'从您的宏中,您的代码将如下所示:
LOG_ERROR(this, LIB_OTHER, "一些错误");
You almost had it. Use
On gcc
LOG_ERROR(this, LIB_OTHER, "some error")
yields
this->log ("ERROR " "at file #a, line #l, function #f: " "some error" " at library " "LIB_OTHER");
I would also remove the trailing ';' from your macro so that your code would look like:
LOG_ERROR(this, LIB_OTHER, "some error");