在编译时提取宏常量中的位数
Extracting the number of digits in a macro constant at compile-time
我需要做一些预处理器魔术。假设我有一个全局常量
#define MAX_VALUE 99999
我需要做的是在编译时提取此常量的十进制表示形式的长度。换句话说,我不想再有一个常量
#define MAX_VALUE_STRLEN 5
污染全局命名空间,我不想在修改MAX_VALUE的情况下在代码中添加需要更改的地方。如果我有一个数字文字,那么我可以做类似
的事情
#define INTLEN(x) (sizeof(#x)/sizeof((#x)[0]) - 1)
然后 INTLEN(99999)
将在编译时扩展为 5
。不幸的是,我不能做类似
的事情
INTLEN(MAX_VALUE),
因为预处理器先展开INTLEN,所以我得到
(sizeof("MAX_VALUE")/sizeof(("MAX_VALUE")[0]) - 1)
是否有预处理器技巧可以实现我想要的?我应该能够安全地忽略的另一个更棘手的问题是,如果有人决定向常量添加类型注释,比如 99999L,我仍然可以获得正确的值,这是否可以变得足够通用?
使用 #
和两级宏扩展进行字符串化,然后切断终止 NUL
:
#define MAX_VALUE 99999
#define STRINGIFY(x) #x
#define LENGTH(x) (sizeof(STRINGIFY(x)) - 1)
#include <stdio.h>
int main()
{
size_t n = LENGTH(MAX_VALUE);
printf("length = %zu\n", n);
return 0;
}
我需要做一些预处理器魔术。假设我有一个全局常量
#define MAX_VALUE 99999
我需要做的是在编译时提取此常量的十进制表示形式的长度。换句话说,我不想再有一个常量
#define MAX_VALUE_STRLEN 5
污染全局命名空间,我不想在修改MAX_VALUE的情况下在代码中添加需要更改的地方。如果我有一个数字文字,那么我可以做类似
的事情#define INTLEN(x) (sizeof(#x)/sizeof((#x)[0]) - 1)
然后 INTLEN(99999)
将在编译时扩展为 5
。不幸的是,我不能做类似
INTLEN(MAX_VALUE),
因为预处理器先展开INTLEN,所以我得到
(sizeof("MAX_VALUE")/sizeof(("MAX_VALUE")[0]) - 1)
是否有预处理器技巧可以实现我想要的?我应该能够安全地忽略的另一个更棘手的问题是,如果有人决定向常量添加类型注释,比如 99999L,我仍然可以获得正确的值,这是否可以变得足够通用?
使用 #
和两级宏扩展进行字符串化,然后切断终止 NUL
:
#define MAX_VALUE 99999
#define STRINGIFY(x) #x
#define LENGTH(x) (sizeof(STRINGIFY(x)) - 1)
#include <stdio.h>
int main()
{
size_t n = LENGTH(MAX_VALUE);
printf("length = %zu\n", n);
return 0;
}