繁体   English   中英

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

[英]Is this memset-memcmp on a struct variable valid C?

它是合法的memset一个struct为某个值,然后将其与比较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字节)。 我有固定的平台和工具链,这些代码现在可以在其中运行,但是如果例如提高优化级别,我可以相信它不会中断吗?


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

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

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

将结构记忆为某个值,然后与memcmp进行比较是否合法?

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

但是,在某些情况下,这可能没有意义。 例如,如果你memcpy从一些未初始化的内存,您将在目的地被垃圾,并利用垃圾可能是不确定的行为

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

从理论上讲,您可能有一些实现使用陷阱表示形式来实现整数值。 实际上,这不会发生。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM