c++ - 在包含 float 的结构上使用 memset()

标签 c++ c double portability cppcheck

在一个 C/C++ 混合项目中,我发现了一些我可以简化为的代码

#include <mem.h>

struct StructContainingDouble
{
    double d;
    /// other elements omitted
};

void clear(StructContainingDouble* p)
{
    memset(p, 0, sizeof *p);
}

不停止 Cppcheck 以引发可移植性警告

Using memset() on struct which contains a floating point number.

消息是正确的,但是由于 float 被声明为 double ,所以它似乎是误报,因为在 double 中,(正)零值是按照 IEEE 754 标准编码的:[*]

0 00000000000 0000000000000000000000000000000000000000000000000000

所以我倾向于简单地抑制警告并忘记它

void clear(ContainingDouble* p)
{
    // cppcheck-suppress memsetClassFloat
    memset(p, 0, sizeof *p);
}

但也许这里真的存在可移植性问题?

附录:

实际代码基于Win32平台。该结构用于管理对 shared memory 的访问,这就是构造函数无用的原因。不仅该结构的一个对象必须归零,而且它的一个数组嵌入到另一个结构中,如下所示:

#include <mem.h>

struct Slot
{
    double d;
    // more members...
};

struct SharedMem
{
    Slot slots[2048];
    // more members...
};

void clear(SharedMem* p)
{
    memset(p, 0, sizeof *p);
}

[*] 来自:Double-precision floating-point format - Wikipedia

最佳答案

有问题吗?是的。不,不是真的。一个非常遥远的也许。

正如 interjay 在评论中指出的那样,C 不强制要求浮点值的格式。因此理论上“零”可能是无效值或不代表零。

所有具有 FPU 的现代平台都实现 IEEE 754。任何(可能是嵌入式)系统都不会在其库中实现 IEEE 754(除非它是退化的实现并且根本没有浮点...)。

因此,虽然不能保证您在这里遇到问题的可能性很小。 在一些平台上存在关于它们如何精确地符合 IEEE 754 信件的细节问题,但之前曾问过但从未得到任何答案我会很高兴看到一个平台,其中 memset()带零的 double 不会将其设置为零值。

就是说,如果您开始将 double up 切碎但使用 0 则不要忘记字节序,这不是问题。

请记住 C 已经接近 50 岁了,现在几乎普遍存在的东西,例如一个字节是 8 位,还没有确定下来,我认为这是正确的,为了提供最大的支持(不要忘记嵌入式)它是从未 promise 遵守这些标准。

在偏执狂模式下你可以:

memset(&obj,0,sizeof obj);
#ifndef __STDC_IEC_559__
    obj.dbl_val=0.0;
#endif

其中 dbl_valobjdouble 成员。然而,未定义的唯一可能原因不是因为 block 归零不是零,而是标准的其他一些优点没有完全实现。

关于c++ - 在包含 float 的结构上使用 memset(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45481484/

相关文章:

c++ - 我们应该测量函数的平均执行时间还是最小执行时间?

c++ - C++ STL中的优先级队列

c - 如何在我的 C 程序中的所有函数中访问数组?

c - 在C中动态分配内存给常量char指针?

Java 正在自行对我的 double 组进行排序。为什么?

c++ - g++ 不产生调试符号

c++ - 尝试将值存储到映射中的std::variant时,std::bad_variant_access错误

c - 拦截来自操作系统的输入

java - DecimalFormat 没有正确四舍五入到两位小数

java - 如果未对金额应用任何操作,BigDecimal.doubleValue() 的准确性如何