CPP:转义宏标识符

CPP: Escaping macro identifiers

本文关键字:标识符 转义 CPP      更新时间:2023-10-16

是否有方法在c预处理器(cpp)中转义宏名称(标识符)?

我想用可读的宏名来约束一些web代码(html, css…)。

条件css文件示例:

/*root*/
some rootcode
#if height==480
/* height 480 */
.page {
    line-height:23px;
}
#elif height<480
/* height < 480 */
.page {
    line-height:46px;
}
#endif

的调用
cpp -P -D height=480 -oout.css css.ccss

导致(删除换行后)

some rootcode
.page {
    line-480:23px;
}

但是"line-480"是错误的。

是否有一种方法可以在不改变宏名称或字符串化的情况下逃避代码中的"高度"?

您可以:

1)取消定义宏:

#undef height

2)使用类似标准的大写字母重命名宏:

#define HEIGHT

3)在处理文件之前使用保护:

#if height==480
#define HEIGHT_480
#undef height
#endif
#if height>480
#define HEIGHT_OVER_480
#undef height
#endif
/*root*/
some rootcode
#if HEIGHT_480
/* height 480 */
.page {
    line-height:23px;
}
#elif HEIGHT_OVER_480
/* height < 480 */
.page {
    line-height:46px;
}
#endif

第一个在undefine之后丢失信息。如果大量使用宏,第二种方法是不切实际的。

在我看来,第三个是最好的选择。我在产品代码中看到过这样的东西。

我使用Luchian Grigore的想法来不定义使用的文件名,并且我找到了这个问题的(几乎)通用解决方案:

包含"define"。条件语句开头的"File"和一个"undefine"。

因此,问题被简化为两个宏名称,必须保留:DEFINEFILE和UNDEFINEFILE。但是,这两个宏可以用它们的哈希码或随机名称进行加密,以避免在条件文本中使用这些名称。

"define.file":

#define height 480
#define os 1
"undefine.file"

#undef height
#undef os
"conditionalcss.ccss"

/*root*/
some rootcode
#include __DEFINEFILENAMEPATH__
#if height==480
#include __UNDEFINEFILENAMEPATH__
/* height 480 */
.page {
    line-height:23px;
}
#include __DEFINEFILENAMEPATH__
#elif height<480
#include __UNDEFINEFILENAMEPATH__
/* height > 480 */
.page {
    line-height:46px;
}
#include __DEFINEFILENAMEPATH__
#endif
#if os==1
#include __UNDEFINEFILENAMEPATH__
os is windows (if 1 refers to windows)
and height also undefined i hope
#endif

最后使用参数化定义和不定义文件的cppcall:

cpp -P -D __DEFINEFILENAMEPATH__=""define.file"" -D __UNDEFINEFILENAMEPATH__=""undefine.file"" -oout.css css.ccss

有了这个想法,结果"out.css"看起来像:

some rootcode
.page {
    line-height:23px;
}
os is windows (if 1 refers to windows)
and height also undefined i hope

该解决方案只有两个宏的缺点,并且由于多次导入可能导致性能较差。

我希望它能帮助别人解决他们的问题。

GreetzAdreamus