使用memcpy避免陷阱表示

时间:2011-12-15 22:05:53

标签: c memcpy

请考虑以下代码:

float float_value = x; // x is any valid float value
int int_value = 0;
size_t size = sizeof(int) < sizeof(float) ? sizeof(int) : sizeof(float);
memcpy(&int_value, &float_value, size);

据我所知,这可能导致陷阱表示。我的问题:

  1. 这是真的吗?
  2. 如果没有,为什么?
  3. 如果没有,是否有其他方法可以避免可能的陷阱表示?

3 个答案:

答案 0 :(得分:10)

不会产生任何陷阱表示的制裁方式是

unsigned char obj[sizeof float];
memcpy(obj, &float_value, sizeof float);

然后,您可以使用对象表示的字节来构建所需的int

但使用Stephen Canon提到的固定宽度整数更好 - 除非你有一个奇怪的float大小。

答案 1 :(得分:3)

如果您只想检查那里的值,则不需要memcpy。最简单的就是施展

unsigned char const* p = &float_object;

指向所有char类型的指针总是保证提供一些有效的,你可以用它来做简单的算术运算。只要你在sizeof float_object给出的范围内取消引用,你就是安全的。

如果要将其视为数字,最安全的是选择固定宽度的无符号整数,最可能是uint32_t。如果您知道宽度要求已经满足,那么这应该可以为您提供所需的一切。

如上所述,只要您不通过该指针进行编写,这种方法就可以正常工作。然后指针的别名规则可能导致优化器出错。

答案 2 :(得分:2)

是的,这可能会导致陷阱表示。至于如何避免它:

  • 断言sizeof(int32_t) == sizeof(float)
  • 使用int32_t代替int

固定宽度整数类型可能不允许陷阱表示。具体来说,标准要求它们没有填充位,并且如果没有填充,则不能使用陷阱表示。