位字段成员的类型

时间:2017-04-03 23:15:35

标签: c++ c bit-fields

理论上,我们有两种选择来选择位字段成员的类型:

  1. 基础类型的类型。
  2. 比特数适合的最小类型。
  3. 那么实际上是什么类型的位域成员(我无法在标准中找到提示 - C和C ++等)并且C和C ++之间有什么区别吗?

    虽然知道特定的编译器不是引用,但我试图通过C ++函数重载和typeid运算符得到至少一些提示:

    #include <typeinfo>
    struct S
    {
        unsigned int n4  :  4;
        unsigned int n12 : 12;
    };
    
    void f(unsigned char)
    {
        std::cout << "uc" << std::endl;
    }
    
    void f(unsigned short)
    {
        std::cout << "us" << std::endl;
    }
    
    void f(unsigned int)
    {
        std::cout << "ui" << std::endl;
    }
    
    int main(int argc, char* argv[])
    {
        S s; s.n4 = 0; s.n12 = 0;
        f(s.n4);
        f(s.n12);
        std::cout << typeid(s.n4).name() << std::endl;
        std::cout << typeid(s.n12).name() << std::endl;
        std::cout << typeid(unsigned char).name() << std::endl;
        std::cout << typeid(unsigned short).name() << std::endl;
        std::cout << typeid(unsigned int).name() << std::endl;
        return 0;
    }
    

    输出(Linux下的GCC 5.4.0)完全令人惊讶,而且 - 至少在我看来 - 是相互矛盾的:

    ui
    ui
    h
    t
    h
    t
    j
    

    因此,如果type,根据typeid运算符,分别是unsigned char和unsigned short,为什么在重载解析期间选择unsigned int?可能甚至是GCC的错误?

    附录:GCC 8.1(linux)仍然表现出相同的行为。

1 个答案:

答案 0 :(得分:1)

来自C++ standard § 10.3.10.1 (class.bit)

  

bit-field属性不是类成员类型的一部分。

(发布问题时,我一定从标准中忽略了这个短语...)

因此,该标准对位字段成员的类型非常清楚,它等于基础类型。

感谢Davis Herring给我适当的提示。