gpt4 book ai didi

c++ - 返回对位域的访问类型

转载 作者:行者123 更新时间:2023-11-30 02:15:43 26 4
gpt4 key购买 nike

#include <iostream>
#include <type_traits>

struct C
{
uint32_t x : 2;
bool y : 2;
};

int main()
{
C c{0b1};

std::cout << (static_cast<uint32_t>(0b1) << 31) << std::endl;
std::cout << (c.x << 31) << std::endl;
std::cout << (c.x << 10) << std::endl;
std::cout << std::boolalpha << std::is_same_v<decltype(c.x), uint32_t> << std::endl;
std::cout << std::boolalpha << std::is_same_v<decltype(c.y), bool> << std::endl;
}

编译

g++ -g  test.cpp -std=c++17

g++ (GCC) 8.2.0

输出

2147483648
-2147483648
1024
true
true

我的问题是关于表达式 c.x 的类型,其中 x 是一个 2 位位域成员。根据 typetraits 检查,我得到的类型与类定义中声明的类型相同,但是在运行时这似乎不是真的,因为当我尝试通过移位设置最后一位时,我得到了一个负数。有什么想法吗?

最佳答案

来自 C++draft 2019-04-12 conv.prom 7.3.6p5 :

7.3.6 Integral promotions

A prvalue for an integral bit-field ([class.bit]) can be converted to a prvalue of type int if int can represent all the values of the bit-field;

来自 C++draft 2019-04-12 expr.shift 7.6.7p1 :

7.6.7 Shift operators

The shift operators << and >> group left-to-right.
...
The operands shall be of integral or unscoped enumeration type and integral promotions are performed.

typeid(c.x)uint32_t , 但是当使用 << 时运算符,它被隐式转换为 int .

c.x0x1 .表达式 c.x << 310x1 << 310x80000000 (假设 sizoef(int) == 4CHAR_BIT == 8 )。此数字被解释为 inttwos complement格式等于-2147483648 ( INT_MIN 或那个 std::intergral_limits<int>::min() )。

请注意表达式 c.x << 31当前 (C++17) 由于有符号整数溢出而调用未定义的行为。

Moreover what is the significance of the type declared in the class definition then?

填充。一些编译器将不同类型的位域解释为“填充分隔符”(不知道如何命名)。如果结构中的下一个成员的类型与前一个成员的类型不同(都是位域),那么我希望编译器将第二个成员从一个新的"new"字节开始放置。我希望 c.xc.y在它们之间填充位,因为它们具有不同的类型。如果是 struct C { uint32_t y : 2; uint32_t x : 2; }那么编译器更有可能将它们放在同一个字节中。请参阅您的编译器文档或 other resources .

关于c++ - 返回对位域的访问类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55806933/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com