c/c++语言开发共享如何避免C中的整数提升?

目前尚不清楚如何使用宽字符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++游戏开发关注(计算机技术网)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ctvol.com/c-cdevelopment/522143.html

      (0)
      上一篇 2020年12月9日
      下一篇 2020年12月9日

      精彩推荐