[英]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.