目前尚不清楚如何使用宽字符API在C中编写可移植代码。 考虑这个例子:
#include #include #include int main(void) { setlocale(LC_CTYPE, "C.UTF-8"); wchar_t wc = L'ÿ'; if (iswlower(wc)) return 0; return 1; }
使用-Wconversion选项使用gcc-6.3.0进行编译会发出以下警告:
test.c: In function 'main': test.c:9:16: warning: conversion to 'wint_t {aka unsigned int}' from 'wchar_t {aka int}' may change the sign of the result [-Wsign-conversion] if (iswlower(wc)) return 0; ^
为了摆脱这个警告,我们转换为(wint_t)
,就像iswlower((wint_t)wc)
,但这是iswlower((wint_t)wc)
移植的。 以下示例说明了为什么它不可移植。
#include /* this is our hypothetical implementation */ typedef signed int wint_t; typedef signed short wchar_t; #define WEOF ((wint_t)0xffffffff) void f(wint_t wc) { if (wc==WEOF) printf("BUG. Valid character recognized as WEOF. This is due to integer promotion. How to avoid it?n"); } int main(void) { wchar_t wc = (wchar_t)0xffff; f((wint_t)wc); return 0; }
我的问题是:如何使这个例子可移植,同时避免gcc警告。
为了简单起见,我将假设我正在讨论的平台/实现具有以下特征:
我也将使用C99作为参考,因为它是我打开的。
该标准说明以下必须适用于这些类型/宏:
请记住,根据C标准的“值”定义, (short int) 0xffff
的值与(int) 0xffffffff
的值相同 – 即它们都具有值-1
(给定在这个答案的开头)。 标准对整数提升的描述(6.3.1.1)清楚地表明了这一点:
如果int可以表示原始类型的所有值,则该值将转换为int; 否则,它将转换为unsigned int。 这些被称为整数促销。 整数促销不会更改所有其他类型。
整数促销保留包括符号在内的值。
我相信当你组合这些元素时,似乎如果WEOF
的值为-1
,那么扩展字符集中的任何项都不能具有值-1
。 我认为这意味着在您的实现示例中, wchar_t
必须是无符号的(如果它仍然是16位类型)或(wchar_t) 0xffff
不能是有效字符。
但是我最初忘记了另一种替代方案(并且可能是您的示例实现的最佳解决方案)是标准在脚注中指出“宏WEOF
值可能与EOF
值不同而且不必为负”。 因此,例如,通过使WEOF == INT_MAX
可以修复您的实现问题。 这样它就不能具有与任何wchar_t
相同的值。
可能与有效字符值重叠的WEOF
值是我认为可能在实际实现中出现的值(即使标准似乎禁止它),并且它类似于关于EOF
可能具有与某些值相同的值的问题。有效的签免费精选名字大全符值。
可能有兴趣的是,对于大多数(所有?)函数可以返回WEOF
来指示某种问题,标准要求函数设置一些关于错误或条件的附加指示(例如,将errno
为特定值,或者在流上设置文件结束指示符)。
另外需要注意的是,我的理解是0xffff是UCS-2或UTF-16中的非字符(不知道可能存在的任何其他16位编码)。
以上就是c/c++开发分享如何避免C中的整数提升?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/522143.html