为什么我不能将类似对象的宏粘贴到函数中?

时间:2017-03-07 19:56:41

标签: c macros

我已经定义了类似对象的宏和类似函数的宏(来自this问题)。

    ID <- map["question.ID"]
    SurveyID <- map["question.SurveyID"]
    Question <- map["question.Question"]
    QuestionType <- map["question.QuestionType"]
    QuestionOrder <- map["question.QuestionOrder"] 

鉴于此定义,#define SYSTEM windows #define CALL(function, ...) (function)(__VA_ARGS__) 变为CALL(foo, arg1, arg2)

我希望foo(arg1, arg2)变为CALL(foo, args)x__foo(args)x定义的内容。

我试过了:

SYSTEM

它们都会导致编译错误。

如何定义#define CALL(function, ...) SYSTEM##__function(__VA_ARGS__) #define CALL(function, ...) (SYSTEM)##__##(function)(__VA_ARGS__) #define CALL(function, ...) ((SYSTEM)##__##(function)(__VA_ARGS__) 以便它连接CALLSYSTEM的值和__的值?

2 个答案:

答案 0 :(得分:6)

您将需要更多级别的间接来连接(粘贴)这些值。 C预处理器尝试将完全粘贴到它看到的内容。如果它看到的是宏或传递给函数的值,它就没有意识到这一点。

  • MACRO##SOMETHINGELSE将生成MACROSOMETHINGELSE
  • (MACRO)##SOMETHINGELSE将在编译时导致错误,因为预处理器正在尝试粘贴括号。
  • SOMETHINGELSE##VALUEPASSEDTOMACRO会产生SOMETHINGVALUEPASSEDTOMACRO

显然,这些都不是你想要的。要添加连接类似于对象的宏值和传递给类函数宏的值所必需的间接,请使用另外两个定义。

#define _cat(x, y) x ## y
#define cat(x, y) _cat(x, y)

然后,您可以定义CALL以满足您的需求。

#define SYSTEM windows
#define CALL(function, ...)   cat(cat(SYSTEM, __), function) (__VA_ARGS__)

根据需要撰写CALL(foobar, x, y)来调用windows__foobar(x, y)

答案 1 :(得分:4)

#define SYSTEM windows
#define PASTE_CALL(prefix, function, ...) prefix ## __ ## function(__VA_ARGS__)
#define EVAL_CALL(prefix, function, ...) PASTE_CALL(prefix, function, __VA_ARGS__)
#define CALL(function, ...) EVAL_CALL(SYSTEM, function, __VA_ARGS__)

CALL(foo, arg1, arg2)

根据需要,这会产生:

# 1 "paste.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "paste.c"





windows__foo(arg1, arg2)