结构变量上的这个 memset-memcmp 是否有效 C?



将结构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进行比较的原因是:我有一个函数,它返回一个位域结构,该结构与我从硬件设备读取的内容匹配,没有浪费的位或字节,并且我想要一种有效的方法来报告错误(设备永远无法返回所有0xFF字节)。我有固定的平台和工具链,代码现在可以工作,但是如果我例如提高优化级别,我可以相信它不会中断吗?


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

你说该函数返回一个"位域结构"。如果您确实返回结构,即按值返回结构,则不,不能保证该行为是您想要的。复制结构时,实现只需要重现其成员中的值,而不是其表示形式中的实际字节。

这同样适用于您的行value2 = invalid_S;

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

是的,因为所有 memset、memcmp、memcpy 都被记录为在任意内存区域上工作(前提是指针和传递给它们的大小指向有效的内存区域)。

但是,在某些情况下,这可能没有意义。例如,如果从某个未初始化的内存memcpy,则会在目标中收到垃圾,并且使用该垃圾可能是未定义的行为。

您正在使用memset0xff.从理论上讲,您可能有一些char大于 8 位的实现(但实际上不会发生这种情况,因此您不在乎)。

理论上,您可能有一些实现具有整数值的陷阱表示。实际上,这种情况不会发生。

如果在具有填充的结构上使用memcmp,则可能无法按预期工作。您可能希望深入了解平台的 ABI 规范,以了解它们是如何实现的(位字段可能未在 ABI 中指定,并且特定于编译器)。

我相信在实践中,您需要很好地了解特定编译器的特定struct的确切布局。看起来您的代码可能是特定于硬件的,那么您不太关心可移植性。因此,在实践中,您的struct S非常相关(也许避免其中的位字段会"更安全")。

相关内容

  • 没有找到相关文章

最新更新