c/c++语言开发共享无符号整数位域移位产生有符号整数

让我们考虑以下程序test.c

 #include  struct test { unsigned int a:5; }; int main () { unsigned int i; struct test t = {1}; for (i = 0; i < ta << 1; i++) printf("%un", i); return 0; } 

使用gcc -Wsign-compare test.c编译时,会生成以下警告(使用gcc 4.8.1进行测试):

 test.c:9:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] for (i = 0; i < ta << 1; i++) ^ 

clang -Wsign-compare test.c生成以下内容(使用clang 3.2进行测试):

 test.c:9:19: warning: comparison of integers of different signs: 'unsigned int' and 'int' [-Wsign-compare] for (i = 0; i < ta << 1; i++) ~ ^ ~~~~~~~~ 1 warning generated. 

因此,右操作数(移位的无符号位字段)变为有符号的int。 此警告显示包含的1到31之间的任何位字段值。 对于更高的值,不会产生警告。 这很奇怪。

这是使用unsigned shortunsigned intunsigned long类型的位字段进行测试的。 后者不会显示包含32到64之间的位字段值的任何警告。

当没有进行移位时没有警告,因此位字段按预期无符号。

为什么大小低于32位的位字段在移位时会被签名? 我认为这不是一个bug,因为这与gccclang都是一致的。 我一定错过了一些关于比特字段(或移位)如何工作的信息但是什么? 如何转换无符号值会产生有符号值?

    整数推广应用于草案C99标准第6.5.7节中所涵盖的转换操作数。 按位移位操作符3段说( 强调我的前进 ):

    对每个操作数执行整数提升。[…]

    6.3.1.1布尔,字符和整数2节中介绍了位域的整数提升,其中说明:

    如果可以使用int或unsigned int,则可以在表达式中使用以下内容:

    并包含以下项目符号:

    – _Bool,int,signed int或unsigned int类型的位字段

    然后说:

    如果int可以表示原始类型的所有值,则该值将转换为int; 否则,它将转换为unsigned int。 这些被称为整数促销48)所有其他类型由整数促销不变。

    在C11标准草案中澄清:

    如果int可以表示原始类型的所有值(由宽度限制,对于位字段) ,该值将转换为int; 否则,它将转换为unsigned int。 这些被称为整数促销。 58)所有其他类型由整数促销不变。

    所以这是预期的行为。

    需要了解更多c/c++开发分享无符号整数位域移位产生有符号整数,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享无符号整数位域移位产生有符号整数相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

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

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/978864.html

      (0)
      上一篇 2021年12月12日
      下一篇 2021年12月12日

      精彩推荐