C++ 14中的有符号位字段

vso*_*tco 7 c++ bit-fields c++14

我相信,直到C++ 14,声明为结构的结构域的某个字段int仍被解释为signed或者unsigned,解释是实现定义的.参考:http://en.cppreference.com/w/cpp/language/bit_field.

在C++ 14中仍然如此吗?即,下面的代码是否保证按照有意义工作?

#include <iostream>

struct X
{
    int f:3;
};

int main() 
{
    X x;
    x.f = -2; // is this going to be indeed signed? It seems so.
    std::cout << x.f << std::endl; // displays -2
}
Run Code Online (Sandbox Code Playgroud)

101*_*010 5

根据C++ 11标准§9.6/ p3比特字段[class.bit](Emphasis Mine):

位字段不应是静态成员.位域应具有整数或枚举类型(3.9.1).它是实现定义是否一个普通的(既没有明确签署也没有无符号)char,short, int,long,或long long位域带符号.bool值可以成功地被存储在任何非零大小的位字段.地址 - 运算符&不应用于位域,因此没有指向位域的指针.非const引用不应绑定到位字段(8.5.3).[注意:如果类型为const T&的引用的初始化程序是引用位字段的左值,则引用绑定到临时初始化以保存位字段的值; 引用不直接绑定到位字段.见8.5.3. - 尾注]

所以你对第一部分是正确的.实际上,直到C++ 14声明的结构的位字段signed仍然被解释为signed或者unsigned,解释是实现定义的.

正如@TC的评论中已经提到的那样.DR739,DR675提到了涉及该问题的缺陷报告.导致C++ 14标准中的以下分辨率:

措辞"据实现定义是否一个普通的(既没有明确签署也无符号)char,short,int,long,或long long位字段是符号或无符号.",除去,以及C++ 14措词现在是:

位字段不应是静态成员.位域应具有整数或枚举类型(3.9.1).bool值可以成功地存储在任何非零大小的位字段中.地址运算符&不应用于位字段,因此没有指向位字段的指针.非const引用不应绑定到位字段(8.5.3).[注意:如果类型为const T&的引用的初始化程序是引用位字段的左值,则引用绑定到临时初始化以保存位字段的值; 引用不直接绑定到位字段.见8.5.3. - 尾注]

同样在§C.1.8第9章:类[diff.class]中添加了以下部分:

9.6

更改: plain int类型的位字段已签名.

理由:将签名选择留给实现可能会导致模板特化的定义不一致.为了保持一致性,非依赖类型的实现自由度也被消除了.

对原始特征的影响:选择是在C中实现定义的,但在C++中则不然.

转换难度:句法转换.

如何广泛使用:很少.

因此,在C++中,14 位类型为plain的位字段int已签名,并且发布的代码保证按预期工作.