gpt4 book ai didi

c - 可移植数据重新解释

转载 作者:太空狗 更新时间:2023-10-29 16:35:37 28 4
gpt4 key购买 nike

我想以一种可移植的方式 (C99) 将一种类型的数据重新解释为另一种类型。我不是在谈论类型转换,我想要对某些给定数据进行重新解释。此外,可移植是指它不会违反 C99 规则 - 我不是是指重新解释的值在所有系统上都是相等的。

我知道 3 种不同的方式来重新解释数据,但其中只有两种是可移植的:

  1. 这不可移植 - 它打破了严格的别名规则。

    /* #1 Type Punning */

    float float_value = 3.14;
    int *int_pointer = (int *)&float_value;
    int int_value = *int_pointer;
  2. 这是依赖于平台的,因为它在写入一个 float 之后从 union 中读取一个 int 值。但它没有违反任何 C99 规则,因此应该可以工作(如果 sizeof(int) == sizeof(float))。

    /* #2 Union Punning */

    union data {
    float float_value;
    int int_value;
    };

    union data data_value;
    data_value.float_value = 3.14;
    int int_value = data_value.int_value;
  3. 应该没问题,只要sizeof(int) == sizeof(float)

    /* #3 Copying */

    float float_value = 3.14;
    int int_value = 0;
    memcpy(&int_value, &float_value, sizeof(int_value));

我的问题:

  1. 这是正确的吗?
  2. 您是否知道以可移植方式重新解释数据的其他方法?

最佳答案

解决方案 2 可移植的 - 通过 union 进行类型双关在 C99 中一直是合法的,并且在 TC3 中明确表示,在第 6.5.2.3 节中添加了以下脚注:

If the member used to access 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.

Annex J 仍然将其列为未指定行为,这是一个已知的缺陷,并已通过 C11 进行了更正,后者发生了变化

The value of a union member other than the last one stored into [is unspecified]

The values of bytes that correspond to union members other than the one last stored into [are unspecified]

这没什么大不了的,因为附件只是提供信息,而不是规范。

请记住,您仍然可能以未定义的行为结束,例如

  • 通过创建陷阱表示
  • 在成员具有指针类型的情况下违反别名规则(无论如何都不应该通过类型双关来转换,因为不需要统一的指针表示)
  • 如果 union 成员有不同的大小——只有最后一次在存储中使用的成员的字节有指定值;特别是,将值存储在较小的成员中也会使较大成员的尾随字节无效
  • 如果一个成员包含填充字节,它总是采用未指定的值

关于c - 可移植数据重新解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8511676/

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