static_assert 宽字符文字的符号性?
static_assert the signedness of wide character literals?
我想 static_assert()
宽字符文字 (L'x'
) 的符号与 wchar_t
.
wchar_t
的定义是我自己的。 (我正在实现一个 C 标准库。)如果用户使用的编译器对宽字符符号的理解与库中配置的不同,我希望尽早失败,大声失败。
断言类型的匹配 size 很容易:
static_assert( sizeof( wchar_t ) == sizeof( L'x' ), "size matches" );
对于内置类型 char
,测试签名很容易。假设某处有一个 _CHAR_IS_SIGNED
定义为 0 或 1,
static_assert( ( (char)-1 < 0 ) == _CHAR_IS_SIGNED, "char is signed" );
成功了。
但是wchar_t
不是内置类型...
有没有办法在 "pure" C99 或 C11 中进行此(静态)断言,即不依赖特定编译器的扩展?
澄清:
我"am"图书馆。我必须 typedef
一些整数类型到 wchar_t
.
编译器——不是我——为某种类型定义了宽字符文字。此类型 未 由编译器分配名称,但理想情况下应与我为 wchar_t
使用的任何名称相同,包括签名(AFAICT 未指定标准)。
我想以某种方式断言/测试这些类型的身份。上面 char
的 (type)-1 < 0
检查不起作用, 因为我无法命名 "the type the compiler uses for literals".
您甚至不需要检查编译器是否对宽字符文字使用有符号或无符号类型。
您可以简单地测试一种宽字符文字是否与您的 typedef 匹配:
static_assert(_Generic(L'.', wchar_t : 1, default : 0), "blahblah");
但是如果你真的想获得类型签名,使用这样的东西:
static_assert(_Generic(L'.', char : ((char)-1 < 0), signed char : 1, short : 1, int : 1, long : 1, long long : 1, default : 0) == _WIDE_CHAR_IS_SIGNED, "blahblah");
而且(正如@chux 所建议的)这是一个更安全的版本,如果宽字符类型与任何标准字符类型都不匹配,它会强制出现编译错误。
#define T(x) signed x : 1, unsigned x : 0 // Makes the code more readable
static_assert(_Generic(L'.', char : ((char)-1 < 0), T(char), T(short), T(int), T(long), T(long long)) == _WIDE_CHAR_IS_SIGNED, "blahblah");
#undef T
我想 static_assert()
宽字符文字 (L'x'
) 的符号与 wchar_t
.
wchar_t
的定义是我自己的。 (我正在实现一个 C 标准库。)如果用户使用的编译器对宽字符符号的理解与库中配置的不同,我希望尽早失败,大声失败。
断言类型的匹配 size 很容易:
static_assert( sizeof( wchar_t ) == sizeof( L'x' ), "size matches" );
对于内置类型 char
,测试签名很容易。假设某处有一个 _CHAR_IS_SIGNED
定义为 0 或 1,
static_assert( ( (char)-1 < 0 ) == _CHAR_IS_SIGNED, "char is signed" );
成功了。
但是wchar_t
不是内置类型...
有没有办法在 "pure" C99 或 C11 中进行此(静态)断言,即不依赖特定编译器的扩展?
澄清:
我"am"图书馆。我必须 typedef
一些整数类型到 wchar_t
.
编译器——不是我——为某种类型定义了宽字符文字。此类型 未 由编译器分配名称,但理想情况下应与我为 wchar_t
使用的任何名称相同,包括签名(AFAICT 未指定标准)。
我想以某种方式断言/测试这些类型的身份。上面 char
的 (type)-1 < 0
检查不起作用, 因为我无法命名 "the type the compiler uses for literals".
您甚至不需要检查编译器是否对宽字符文字使用有符号或无符号类型。
您可以简单地测试一种宽字符文字是否与您的 typedef 匹配:
static_assert(_Generic(L'.', wchar_t : 1, default : 0), "blahblah");
但是如果你真的想获得类型签名,使用这样的东西:
static_assert(_Generic(L'.', char : ((char)-1 < 0), signed char : 1, short : 1, int : 1, long : 1, long long : 1, default : 0) == _WIDE_CHAR_IS_SIGNED, "blahblah");
而且(正如@chux 所建议的)这是一个更安全的版本,如果宽字符类型与任何标准字符类型都不匹配,它会强制出现编译错误。
#define T(x) signed x : 1, unsigned x : 0 // Makes the code more readable
static_assert(_Generic(L'.', char : ((char)-1 < 0), T(char), T(short), T(int), T(long), T(long long)) == _WIDE_CHAR_IS_SIGNED, "blahblah");
#undef T