用工会检测病情是否安全? [英] Is it safe to detect endianess with union?

查看:60
本文介绍了用工会检测病情是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

换句话说,根据C 标准,此代码安全吗? (假设uint8_t是一个字节)

In other words, according to the C standard, is this code safe? (Assume uint8_t is one byte)

void detectEndianness(void){
    union {
        uint16_t w;
        uint8_t b;
    } a;
    a.w = 0x00FFU;
    if (a.b == 0xFFU) {
        puts("Little endian.");
    }
    else if (a.b == 0U) {
        puts("Big endian.");
    }
    else {
        puts("Stack Overflow endian.");
    }
}

如果我将其更改为该怎么办?请注意我所知道的第三种if情况.

What if I change it into this? Note the third if case that I'm aware of.

a.w = 1U;
if (a.b == 1U) { puts("Little endian."); }
else if (a.b == 0U) { puts ("Big endian."); }
else if (a.b == 0x80U) { /* Special potential */ }
else { puts("Stack Overflow endian."); }

推荐答案

引用自n1570:

6.5.2.3结构和联合成员-p3

后缀表达式,后跟.运算符和标识符 指定结构或联合对象的成员. 值是 ,并且如果第一个表达式是 左值.

A postfix expression followed by the . operator and an identifier designates a member of a structure or union object. The value is that of the named member, and is an lvalue if the first expression is an lvalue.

6.2.6类型的表示形式/1一般-p7

当值存储在联合类型的对象的成员中时, 与之不对应的对象表示形式的字节 成员,但确实与其他成员相对应,但未指定值.

When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.

允许.如果注释95 (尽管仅提供信息):

It's allowed. And your use case could even be considered one intended purpose, if note 95 is taken into account (despite being only informative):

如果用于读取联合对象内容的成员不是 与上次用于在对象中存储值的成员相同, 对象表示的适当部分的值是 重新描述为新类型的对象表示形式,如所述 在6.2.6中(有时称为类型校正"的过程).这可能是 陷阱表示.

If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation.

现在,由于uintN_t系列类型被定义为没有填充位

Now, since the uintN_t family of types are defined to have no padding bits

7.20.1.1精确宽度整数类型-p2

typedef名称uintN_t用以下方式指定无符号整数类型: 宽度N,无填充位.因此,uint24_t表示这样的无符号 整数类型,宽度恰好为24位.

The typedef name uintN_t designates an unsigned integer type with width N and no padding bits. Thus, uint24_t denotes such an unsigned integer type with a width of exactly 24 bits.

它们的所有位表示都是有效值,不能使用陷阱表示.因此,我们必须得出结论,它确实会检查uint16_t的字节序.

All their bit representations are valid values, no trap representations are possible. So we must conclude that it will indeed check for the endianess of uint16_t.

这篇关于用工会检测病情是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆