我想static_assert()广泛的字符文字(L'x')的签名与wchar_t.
定义wchar_t是我自己的.(我正在实现一个C标准库.)如果用户使用的编译器对宽字符签名的概念与库中配置的不同,我想尽早失败,大声失败.
断言匹配大小的类型很容易:
static_assert( sizeof( wchar_t ) == sizeof( L'x' ), "size matches" );
Run Code Online (Sandbox Code Playgroud)
对于内置类型char,测试签名很容易.假设在_CHAR_IS_SIGNED某处定义为0或1,
static_assert( ( (char)-1 < 0 ) == _CHAR_IS_SIGNED, "char is signed" );
Run Code Online (Sandbox Code Playgroud)
诀窍.
但是,wchar_t是不是一个内置式...
有没有办法在"纯"C99或C11中进行此(静态)断言,即不依赖于特定编译器的扩展?
澄清:
我"是"图书馆.我必须要typedef一些整数类型wchar_t.
编译器 - 不是我 - 将宽字符文字定义为某种类型.编译器未为此类型指定名称,但理想情况下应与我使用的任何名称相同wchar_t,包括签名(其中,AFAICT,未由标准指定).
我想以某种方式断言/测试这些类型的身份.上面(type)-1 < 0显示的检查char不起作用,因为我不能命名"编译器用于文字的类型".
您甚至不需要检查编译器是否使用有符号或无符号类型来表示宽字符文字.
您可以简单地测试一种宽字符文字是否与您的typedef匹配:
static_assert(_Generic(L'.', wchar_t : 1, default : 0), "blahblah");
Run Code Online (Sandbox Code Playgroud)
但如果你真的想获得类型签名,请使用以下内容:
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");
Run Code Online (Sandbox Code Playgroud)
并且(如@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
Run Code Online (Sandbox Code Playgroud)