10

我想做的(用于记录目的)是这样的:

编写此代码是为了显示我的问题,实际代码很复杂,是的,即使在 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,在调用之前未扩展宏)

有什么方法可以在不使用技巧的情况下获得相同的行为?

4

4 回答 4

9

我正在做:

#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++


编辑:要使其与 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
于 2009-12-10T13:33:21.010 回答
4

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.

于 2009-12-10T15:39:56.590 回答
0

我不认为你可以。但是,您可以做的是添加一层宏以使其在其位置上剥离:

#define WRAP(x) x
#define LOG_ERROR(ptr, lib, str) LOG_ERROR_SIMPLE(ptr, lib, WHERE WRAP(str))
于 2009-12-10T13:10:44.247 回答
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");

于 2009-12-10T14:11:24.787 回答