我希望static_assert()
广泛字符文字(L'x'
)的签名与wchar_t
的签名相符。
wchar_t
的定义是我自己的。 (我正在实现一个C标准库。)如果用户使用的编译器对宽字符签名的概念与库中配置的不同,我想尽早失败,大声失败。
断言匹配的大小类型非常简单:
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
不是内置类型......
有没有办法在“纯”C99或C11中进行此(静态)断言,即不依赖于特定编译器的扩展?
澄清:
我“是”图书馆。我必须typedef
某种整数类型为wchar_t
。
编译器 - 不是我 - 将宽字符文字定义为某种类型。此类型不由编译器分配名称,但理想情况下应与我wchar_t
使用的任何名称相同,包括签名(其中,AFAICT,未由标准指定)。
我想以某种方式断言/测试这些类型的身份。上面针对(type)-1 < 0
显示的char
检查不起作用,因为我无法命名“编译器用于文字的类型”。
答案 0 :(得分:5)
您甚至不需要检查编译器是否使用有符号或无符号类型来表示宽字符文字。
您可以简单地测试一种宽字符文字是否与您的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