如何检查宏参数是否是 C 中的整数文字

问题描述 投票:0回答:1

我正在尝试做一个这样的宏:

#define STRING(i) \
struct STRING##i \
{ \
    size_t len; \
    char chars[i]; \
}

但问题是这适用于像这样的

constexpr
参数:

constexpr int ten = 10;
STRING(ten) mystr;

我不希望这样,因为

STRING(ten)
STRING(10)
不是兼容的类型,这可能会让这个宏的用户感到困惑。

我尝试了以下方法:

#define STRING(i) \
struct STRING##i \
{ \
    _Static_assert( CAT(i, ul) , "must be nonzero literal"); \
    size_t len; \
    char chars[i]; \
}

它将

ul
附加到文字并使其成为无符号长文字,但对于非文字会失败,因为它使其成为不同的标识符。但问题是,如果用户有另一个名为
constexpr
tenul
,例如。

我想知道是否有更好的方法让这个宏失败,除非提供整数文字。

c macros c23
1个回答
0
投票

有效标识符以字母字符或下划线开头。有效的整数文字以数字开头。如果有一种方法可以在编译时检查

#i
(宏参数转换为字符串)的第一个字符是否是数字。但据我所知,使用 (#i)[0]
 仅在运行时有效。

问题被标记为

c23仅适用于C23的方法:

在 6.6 常量表达式中:

从结构体或联合常量开始,成员访问 .如上所述,运算符可用于形成命名常量或复合文字常量。

这意味着理论上您可以:

#define IS_LITERAL(i)\ _Static_assert(((constexpr union {unsigned char f, s[sizeof(#i)];}){.s = #i}).f - '0' <= 9,\ "Not numeric literal");
它的作用是创建一个包含 

char

 字段和 
char[]
 字段的常量匿名联合,并使用 
.
 运算符获取 
char
 字段,该字段将成为 
char[]
 字段的第一个字符,然后检查字符是否为数字。

© www.soinside.com 2019 - 2024. All rights reserved.