【问题标题】:struct binary representation in c++C ++中的结构二进制表示
【发布时间】:2021-09-29 13:07:14
【问题描述】:

这是我的代码:

#include <iostream>


//extract i:th bit from val of given addr with &
void extractBit(long long unsigned* ptr,int ith) {
    std::cout << (*ptr & (1LLU << ith) ? 1 : 0);
}


template <typename T> void printlnbits(T v)
{
    //v_size to hold the size of the generic variable
    const int v_size = sizeof(v) * 8;
    int j = 0;

    unsigned long long int* ptr = reinterpret_cast<unsigned long long int*>(&v);
        
    for (int n = v_size - 1; n >= 0; --n)
    {
        j++;
        extractBit(ptr, n);

        if (j == 8)
        {
            std::cout << " ";
            j = 0;
        }
    }
    std::cout << "\t" << v_size << std::endl;
}

struct foo {
    int a = 2;
    char b = -1;
    unsigned long long int x = 1LLU << 63;
};

int main() {
    const char a = 'a'; //97, displayed binary: 01100001, size:8bit
    const foo b; /*displayed binary: 00000000 00000000 00000000 00000000 00000000 000000000 00000000 00000000 11001100 11001100 11001100 11111111 00000000 00000000 00000000 00000010 
size: 128bit
*/

    printlnbits(a);
    printlnbits(b);
    return 0;
}

char 'a' 的 ascii 值为 97,二进制表示为: 01100001。 char 的大小为 8 位。

结构值是我无法理解的。 它用以下值表示: 14757395474574999554,或二进制: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11001100 11001100 11001100 11111111 00000000000000000000000000000000000000000000

结构体的大小为 128 位。据我了解是这样存储的:

|----------------------------------------------|
| int a: 32bit | char b: 8bit | padding: 24bit-|
|----------------------------------------------|
|--------unsigned long long int x: 64bit-------|
|----------------------------------------------|

如您所见,该结构由一个非常奇数的二进制数表示。 哪种方法用于以二进制形式存储给定变量的结构? 我试图为它找到任何 IEEE 标准但没有任何成功..

【问题讨论】:

  • 您的代码有未定义的行为。您不能通过将 foo 强制转换为 long long* 来访问其部分
  • 不是 IEEE,是 ISO 14882
  • 如果你使用g++ 或clang++ 编译,使用-g -fsanitize=address,undefined 编译你会看到something like this - 这通常会有所帮助
  • 你永远不会前进ptr,所以你一直在移动相同的值。
  • 前 64 位是结构的初始 64 位 - a、b 和填充 - 向左移动了太远(正式未定义,但显然在此产生零特殊案例)。接下来的 24 位是填充。然后你有b (11111111) 和a (0000...0010)。

标签: c++ struct memory-management bitwise-operators bit-representation


【解决方案1】:

最后 8 个字节的值实际上是正确的一个,包括填充。但是你向后打印结构,

for (int n = v_size - 1; n >= 0; --n)

所以a 的值是向后的最后 4 个字节。在小端的情况下,只有单个字段受字节顺序的影响,按位移位操作与字节顺序无关,因此您可以看到正确的字节值。

此外,您永远不会超过前 64 位,因为 ptr 值不会改变。应该是这样的

extractBit(ptr + n /  8*sizeof(long long int), n %  8*sizeof(long long int) );

正如 Nathan 在评论中提到的,您的访问模式正式导致未定义的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    相关资源
    最近更新 更多