首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可能基于预处理器生成的“事物”#if或#ifdef

可能基于预处理器生成的“事物”#if或#ifdef
EN

Stack Overflow用户
提问于 2010-09-03 12:56:03
回答 1查看 402关注 0票数 0

我试图参与一些C-preprocessor-only模板工作,以便键入一些代码。我试着把它简化一些,所以这个例子看起来很琐碎,毫无意义,但真正的挑战是如何获得“包含”阻塞。

假设我有一个“模板”文件,它在包含模板之前从定义T_ELEMENT_TYPE的其他源文件中获得#。

代码语言:javascript
复制
// Template file...
#ifndef T_ELEMENT_TYPE
#error #define T_ELEMENT_TYPE
#endif

#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SYMBOLNAME EVALUATOR(SymbolFor, T_ELEMENT_TYPE)

#ifndef SYMBOLNAMEISDEFINED
#define SYMBOLNAMEISDEFINED EVALUTOR(DEFINEDFOR, T_ELEMENT_TYPE)

int SYMBOLNAME(T_ELEMENT_TYPE arg)
{
    // do something with arg
    return 0;
}

#endif // Guard #ifdef

然后,我希望包含来自多个实例化站点的模板,但我只希望每个惟一的T_ELEMENT_TYPE生成一次模板函数(这样就不会创建重复的符号)。就像,说:

代码语言:javascript
复制
// Template-using file...    
#define T_ELEMENT_TYPE int
#include "Template.c"
#undef T_ELEMENT_TYPE

#define T_ELEMENT_TYPE float
#include "Template.c"
#undef T_ELEMENT_TYPE

#define T_ELEMENT_TYPE int
#include "Template.c"
#undef T_ELEMENT_TYPE

int someOtherFunc()
{
    int foo = 42;
    foo = SymbolForint(foo);
    float bar = 42.0;
    bar = SymbolForfloat(bar);
    return foo;
}

所以我在寻找一些我可以在模板代码中使用的东西。我想象它可能看起来像这样(虽然这不起作用):

代码语言:javascript
复制
// Template file...
#ifndef T_ELEMENT_TYPE
#error #define T_ELEMENT_TYPE
#endif

#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SYMBOLNAME EVALUATOR(SymbolFor, T_ELEMENT_TYPE)

#ifndef SYMBOLNAMEISDEFINED
#define SYMBOLNAMEISDEFINED EVALUTOR(DEFINEDFOR, T_ELEMENT_TYPE)

int SYMBOLNAME(T_ELEMENT_TYPE arg)
{
    // do something with arg
    return 0;
}

#endif // Guard #ifdef

这个特定的咒语阻止模板的所有多个实例化,而不仅仅是针对不同的T_ELEMENT_TYPE值。

我能用什么伎俩来达到这个效果吗?或者说,我只是取消了C-Preprocessor的预订?

EN

回答 1

Stack Overflow用户

发布于 2010-09-03 14:09:14

我想你已经离开保留地了。宏名#define的第一个“参数”不受宏扩展的限制。因此,我认为预处理程序不能根据T_ELEMENT_TYPE的值定义不同的符号。预处理器也不能构造一个已经看到的类型的“列表”,并在其中检查是否存在。

所以我认为包括守卫必须在档案之外:

代码语言:javascript
复制
#ifndef included_mytemplatefile_h_int
    #undef T_ELEMENT_TYPE
    #define T_ELEMENT_TYPE int
    #include "mytemplatefile.h"
    #define included_mytemplatefile_h_int
#endif

或者,如果您的模板文件头只声明函数SymbolFor_int,而不是定义它,那么多个包含是无害的。您可以在文件中不依赖于T_ELEMENT_TYPE当前值的部分周围设置一个普通的包含保护,包括PASTER、计算器、SYMBOLNAME的定义。您需要一个包含定义的单独模板文件,程序(而不是每个翻译单元)只需要拥有一次定义:

代码语言:javascript
复制
template_%.c :
    echo "#define T_ELEMENT_TYPE $*" > $@
    echo "#include \"mytemplatedefinitions.c\"" >> $@

然后将template_int.o添加到链接到程序中的文件列表中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3635921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档