将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字节)。我有固定的平台和工具链,代码现在可以使用,但是如果我提高优化级别,我可以相信它不会中断吗?
结论:虽然如果我确定没有填充位,浮点字段等可能有问题,这个代码可以工作,但我决定只将一个特定的结构字段设置为特定的“不可能”值来指示错误。
将结构体设置为某个值是否合法,然后将其与memcmp进行比较?
是的,因为所有的qazxsw poi,qazxsw poi,qazxsw poi都记录在任意内存区域上工作(假设指针和传递给它们的大小指向一个有效的内存区域)。
但是,在某些情况下,这可能没有意义。例如,如果您从某些未初始化的内存中获取memset,您将在目标中获得垃圾,并使用该垃圾可能是memcmp。
你正在使用memcpy和memcpy
。理论上,你可能有一些实现,其中undefined behavior大于8位(但在实践中,这不会发生,所以你不在乎)。
理论上你可能有一些实现具有整数值的陷阱表示。在实践中,这不会发生。
如果你在memset
的结构上使用0xff
可能无法正常工作。您可能希望深入了解平台的char
规范,以了解它们的实现方式(并且可能未在ABI中指定位域并且特定于编译器)。
我相信在实践中你需要用你的特定编译器很好地理解你的特定memcmp
的确切布局。看起来您的代码可能是特定于硬件的,那么您对可移植性并不在意。所以在实践中你的padding是非常相关的(也许避免它中的位域会“更安全”)。
你说该函数返回一个“位域结构”。如果你真的返回一个结构,即按值返回一个结构,那么不行,并不能保证你想要的行为。复制结构时,实现只需要在其成员中重现值,而不是其表示中的实际字节。
这同样适用于你的ABI系列。