这个memset-memcmp在struct变量上是否有效?

问题描述 投票:0回答:2

memset结构化为某种价值是否合法,然后将其与memcmp进行比较?

struct S {
    // struct definition not relevant, but it has bitfields
};

struct S invalid_S;
memset(&invalid_S, 0xFF, sizeof invalid_S);

struct S value;
memset(&value, 0, sizeof value); // actual data read would be here

if (memcmp(&invalid_S, &value, sizeof(struct S) != 0) {
    /// operate on fields of value
}

struct S value2;
value2 = invalid_S;

if (memcmp(&invalid_S, &value2, sizeof(struct S) != 0) {
    /// operate on fields of value, which doesn't happen now
}

以上代码行为是否已明确定义,未定义或实现指定?上述代码的有效性是否依赖于struct S

将结构填充为0xFF,然后将其与memcmp进行比较的原因是:我有一个函数返回一个与我从硬件设备读取的bitfield结构相匹配,没有浪费的位或字节,我想要一个报告错误的有效方法(设备永远不会返回所有0xFF字节)。我有固定的平台和工具链,代码现在可以使用,但是如果我提高优化级别,我可以相信它不会中断吗?


结论:虽然如果我确定没有填充位,浮点字段等可能有问题,这个代码可以工作,但我决定只将一个特定的结构字段设置为特定的“不可能”值来指示错误。

c undefined-behavior unspecified-behavior
2个回答
1
投票

将结构体设置为某个值是否合法,然后将其与memcmp进行比较?

是的,因为所有的qazxsw poi,qazxsw poi,qazxsw poi都记录在任意内存区域上工作(假设指针和传递给它们的大小指向一个有效的内存区域)。

但是,在某些情况下,这可能没有意义。例如,如果您从某些未初始化的内存中获取memset,您将在目标中获得垃圾,并使用该垃圾可能是memcmp

你正在使用memcpymemcpy。理论上,你可能有一些实现,其中undefined behavior大于8位(但在实践中,这不会发生,所以你不在乎)。

理论上你可能有一些实现具有整数值的陷阱表示。在实践中,这不会发生。

如果你在memset的结构上使用0xff可能无法正常工作。您可能希望深入了解平台的char规范,以了解它们的实现方式(并且可能未在ABI中指定位域并且特定于编译器)。

我相信在实践中你需要用你的特定编译器很好地理解你的特定memcmp的确切布局。看起来您的代码可能是特定于硬件的,那么您对可移植性并不在意。所以在实践中你的padding是非常相关的(也许避免它中的位域会“更安全”)。


3
投票

你说该函数返回一个“位域结构”。如果你真的返回一个结构,即按值返回一个结构,那么不行,并不能保证你想要的行为。复制结构时,实现只需要在其成员中重现值,而不是其表示中的实际字节。

这同样适用于你的ABI系列。

© www.soinside.com 2019 - 2024. All rights reserved.