簡體   English   中英

CPP:避免宏功能參數的宏擴展

[英]CPP: avoiding macro expansion of a macro function parameter

我想做的(用於記錄目的)是這樣的:

編寫此代碼是為了顯示我的問題,實際代碼很復雜,是的,我有充分的理由在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 ,在調用之前不會擴展宏)

有一些方法可以在不使用技巧的情況下獲得相同的行為?

我正在做:

#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

如果在cpp宏中不需要擴展的lib別名(即“1”和“2”),則還可以使用枚舉而不是定義的值。

我認為你不能。 但是,你可以做的是為它添加一層宏來取消它的位置:

#define WRAP(x) x
#define LOG_ERROR(ptr, lib, str) LOG_ERROR_SIMPLE(ptr, lib, WHERE WRAP(str))

你幾乎擁有它。 使用

#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") ;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM