一个项目是否有能力编译代码,需要知道哪些代码被包含,哪些不包含。这些功能全部隔离在单个文件中,其中的代码包含在
#ifdef UPPERCASE_FILENAME_C ...code... #endif
中,为了使处理更简单,我们检查了一些预处理器“魔法”
#define STRINGIZE(x) __STRINGIZE(x)
#define __STRINGIZE(x) ""#x""
#define MP_HAS(x) (sizeof(STRINGIZE(x##_C)) == 1u )
如果定义了有问题的宏,它将扩展为一个大小为 1 的空字符串(只有
\0
被计算在内),如果没有,则给定的整个字符串将被扩展,解析为一个值 >1
.
可以玩的东西:
#include <stdlib.h>
#include <stdio.h>
#ifdef DEFINE_IT
#define FOOT_C
#endif
#define STRINGIZE(x) __STRINGIZE(x)
#define __STRINGIZE(x) ""#x""
#define HAVE_WE(x) (sizeof(STRINGIZE(x##_C)) )
int main(void) {
printf("sizeof(stringized) = %zu\n", HAVE_WE(FOOT));
exit(EXIT_SUCCESS);
}
到目前为止,还不错。有点复杂,但它有效。
但是:如果我们在命令行给出定义(以测试所有分支)
gcc -DFOOT_C sizeoftest.c -o sizeoftest
宏扩展为 1
,因此字符串不再为空并且 sizeof
为 2(二),字符 1
和角色 \0
.
一种解决方法是将命令行给出的定义明确设置为空字符串:
gcc -DFOOT_C="" sizeoftest.c -o sizeoftest
.
有没有办法调整 stringify 宏以忽略这种差异并处理两种方式以相同的方式定义宏?