我们说我有以下宏定义(包括行号):
41 #define MACRO1
.
.
52 #define MACRO2
如何定义MACRO1,以便在编译时将其解析为与MACRO1定义的行号相对应的数字? (在这种情况下为41)
如何定义MACRO2,以便在编译时将其解析为预定义字符串(例如foo)和数字X的串联,其中X等于MACRO2(52)的行号之间的差值和MACRO1(41)的行号?
鉴于上述情况,MACRO2将解析为foo11,因为它是预定义字符串' foo'之间的串联。以及2行数52和41之间的差异。
这可能吗?
答案 0 :(得分:4)
您无法使用通常的C preprocessor执行所需操作。阅读documentation of cpp
。
但是,请记住,可以生成C(或C ++等)文件(通过某些程序或脚本)。您可以为该代使用一些其他预处理器(例如m4或GPP,或您自己的脚本或程序。)
然后,您只需为此目的配置build automation。如果您使用GNU make
,请修改build.ninja
;如果您使用ninja,请修改您的 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.my_app_bar);
//((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
//return inflater.inflate(R.layout.fragment_training, container, false);
View v = inflater.inflate(r.layout.fragment_training, container, false);
Toolbar toolbar = (Toolbar) v.findviewbyid(r.id.my_app_bar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
return v;
}
文件等....
这种基本metaprogramming技术在实践中非常普遍;在许多大型程序中,生成了一些C或C ++代码。一些生成器(例如bison或rpcgen)非常常见,并且出现在上个世纪。
例如,GCC编译器(主要用C ++编写)有大约十几个C ++代码生成器。
请注意,现代operating systems启用plugins及其dynamic loading;所以在某些情况下甚至值得在运行时生成一些C或C ++代码,将其编译为插件,然后加载它(例如在Linux上使用dlopen(3)使用dlsym(3))来使用它。然后要小心name mangling。还可以考虑使用JIT compiling或GCCJIT之类的LLVM库......
BTW,最新的C ++编译器可以使用插件(例如GCC plugins)进行扩展,或者用作库(例如libclang)。许多(学术或特定领域)语言是compiled to C,有些是编译成C ++(例如felix)。