c - 为什么这种检测机器存储方式的方法不正确? (使用C语言)

标签 c cpu-architecture

我在做作业时漏掉了一个问题。

计算机内存中存储数据的地方有大端存储和小端存储两种方式,为了检测某台机器的存储方式,某同学写了如下程序:

union NUM {
    int a;
    char b;
} num;

int main(){
    num.b = 0xff;
    if (num.a! = 0xff)
        printf ("bigend");
    else 
        printf ("smallend");
    return 0;
}

但是他发现在x86机器上运行的程序,打印出来的居然是'bigend',这显然是错误的。你知道问题出在哪里吗? 这个程序应该如何修改?

问过老师,题目是对的。我在一些网站上找到了一些信息,但它让我更加困惑。为什么这个问题没有错?问题究竟出在哪里?

最佳答案

假设 int(因此 union 作为一个整体)是 4 个字节,写入 num.b 只会写入这 4 个字节中的一个,剩下的未初始化。随后读取 num.a 读取那些未初始化的字节,调用 undefined behavior .

union 中的字节必须设置为全0,以便内容定义明确。

#include <stdio.h>
#include <string.h>

union NUM {
    int a;
    char b;
} num;

int main(){
    // set all bytes of num to 0 first
    memset(&num, 0, sizeof(num));
    num.b = 0xff;
    if (num.a! = 0xff)
        printf ("bigend");
    else 
        printf ("smallend");
    return 0;
}

关于c - 为什么这种检测机器存储方式的方法不正确? (使用C语言),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46730849/

相关文章:

x86 - 现代 x86 CPU 使用什么缓存一致性解决方案?

c++ - 如何反汇编编译器生成的代码?

c - 如何在c中使用libcurl上传文件

c - 带链表的多项式和

c - 多个字之间的高效位混洗

mips - 为什么 'opcode' 字段和 'funct' 字段在 MIPS 中是分开的?

cpu - 正确的分支预测是免费的吗?

c - Linux 内核模块中的 Linux 实模式接口(interface)

c - 具有可变长度数组类型的 Sizeof 运算符

ios - 是否有编译器标志指示缺少 armv7s 架构