我正在尝试编写一个程序,其中一些函数的名称依赖于某个宏变量的值,宏如下:
#define VARIABLE 3
#define NAME(fun) fun ## _ ## VARIABLE
int NAME(some_function)(int a);
Run Code Online (Sandbox Code Playgroud)
不幸的是,宏NAME()将其转化为
int some_function_VARIABLE(int a);
Run Code Online (Sandbox Code Playgroud)
而不是
int some_function_3(int a);
Run Code Online (Sandbox Code Playgroud)
所以这显然是错误的方式.幸运的是,VARIABLE的不同可能值的数量很小所以我可以简单地做一个#if VARIABLE == n并单独列出所有情况,但我想知道是否有一个聪明的方法来做到这一点.
至少有一些C预处理器允许你将宏的值(而不是它的名称)通过一个类似函数的宏传递给另一个将它串行化的宏来进行字符串化:
#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
Run Code Online (Sandbox Code Playgroud)
这里的用例示例.
这确实有效,至少在GCC和Clang(两者都有-std=c99),但我不确定它是如何工作的C标准术语.
这种行为是否由C99保证?
如果是这样,C99如何保证呢?
如果不是,那么从C定义到GCC定义的行为在什么时候?
我想为宏程序动态创建的包含文件路径,用于程序的目标配置相关部分.
例如,我想构建一个可以像这样调用的宏:
#include TARGET_PATH_OF(header.h)
Run Code Online (Sandbox Code Playgroud)
这会扩展到这样的事情:
#include "corefoundation/header.h"
Run Code Online (Sandbox Code Playgroud)
当为OSX配置源(在本例中)时
到目前为止,所有尝试都失败了 我希望以前有人这样做过吗?
什么不起作用的例子:
#include <iostream>
#include <boost/preprocessor.hpp>
#define Dir directory/
#define File filename.h
#define MakePath(f) BOOST_PP_STRINGIZE(BOOST_PP_CAT(Dir,f))
#define MyPath MakePath(File)
using namespace std;
int main() {
// this is a test - yes I know I could just concatenate strings here
// but that is not the case for #include
cout << MyPath << endl;
}
Run Code Online (Sandbox Code Playgroud)
错误:
./enableif.cpp:31:13: error: pasting formed '/filename', an invalid preprocessing token
cout << MyPath << endl;
^
./enableif.cpp:26:16: …Run Code Online (Sandbox Code Playgroud)