首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在int数组上使用memcmp是否严格一致?

在int数组上使用memcmp是否严格一致?
EN

Stack Overflow用户
提问于 2012-08-16 19:54:34
回答 1查看 4.1K关注 0票数 26

下面的程序是C中严格一致的程序吗?我对c90和c99感兴趣,但是c11的答案也是可以接受的。

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

struct S { int array[2]; };

int main () {
    struct S a = { { 1, 2 } };
    struct S b;
    b = a;
    if (memcmp(b.array, a.array, sizeof(b.array)) == 0) {
        puts("ok");
    }
    return 0;
}

comments to my answer in a different question中,Eric坚持认为程序输出将根据平台的不同而改变,这主要是因为可能存在未初始化的填充位。我认为结构赋值将覆盖b中的所有位,使其与a中的相同。但是,C99似乎没有提供这样的保证。来自6.5.16.1节p2:

在简单赋值(=)中,右操作数的值被转换为赋值表达式的类型,并替换存储在左操作数指定的对象中的值。

在复合类型中,“转换”和“替换”是什么意思?

最后,考虑相同的程序,但ab的定义是全局的。那个程序会是严格一致的程序吗?

编辑:只是想在这里总结一些讨论材料,而不是添加我自己的答案,因为我实际上没有自己的创作。

  • 程序不严格一致。由于赋值是由值而不是由表示来分配的,所以b.array可能包含或不包含与a.array不同的位。
  • a不需要转换,因为它是与b相同的类型,但是替换是按值进行的,并且是按成员进行的。
  • 即使ab中的定义是全局的、后赋值的,b.array也可能包含与a.array不同的位。(很少有人讨论b中的填充字节,但发布的问题不是关于结构比较。c99没有提到填充是如何在静态存储中初始化的,但是c11明确声明它是零初始化的。)
  • 另外,如果使用来自memcmpmemcpy初始化b,则可以很好地定义b

我感谢所有参与讨论的人。

EN

回答 1

Stack Overflow用户

发布于 2012-08-16 21:23:06

我的看法是,这是严格一致的。根据埃里克·波斯特皮奇尔提到的4.5条:

严格符合标准的程序只应使用本国际标准中规定的语言和库的特性。它不应产生依赖于任何未指定的、未定义的或实现定义的行为的输出,并且不应超过任何最低实现限制。

所讨论的行为是memcmp的行为,这是定义良好的,没有任何未指定的、未定义的或实现定义的方面。它在表示的原始位上工作,而不知道任何关于值、填充位或陷阱表示的信息。因此,结果(但在这种特殊情况下不依赖于memcmp的)取决于存储在这些字节内的值的实现。

(第6.2.6.2条脚注43):

具有相同有效类型T的对象x和y在作为T类型对象访问时有可能具有相同的值,但在其他上下文中具有不同的值。特别是,如果为类型T定义了==,那么x == y并不意味着memcmp(&x,&y,sizeof (T)) == 0。此外,x == y并不一定意味着x和y具有相同的值;对T类型值的其他操作可能会区分它们。

编辑:

再想一想,我不太确定严格的一致性了,因为这一点:

它不应产生依赖于的输出任何未指定的.

显然,memcmp的结果依赖于表示的未指定的行为,从而实现了这个子句,尽管memcmp本身的行为定义得很好。在输出发生之前,该子句不会说任何关于功能深度的内容。

因此,这是而不是严格一致的。

编辑2:

我不太确定当memcpy用于复制结构时,它是否会成为严格的一致性。根据附件J,未指定的行为发生在初始化a时:

代码语言:javascript
复制
struct S a = { { 1, 2 } };

即使我们假设填充位不会改变,并且memcpy总是返回0,它仍然使用填充位来获得其结果。它依赖于这样的假设,即它们不会改变,但在这方面的标准中没有保证。

我们应该区分用于对齐的结构中的填充字节和特定本机类型(如int )中的填充位。虽然我们可以安全地假设填充字节不会改变,但这只是因为没有真正的原因,但同样的情况并不适用于填充位。标准提到一个奇偶校验标志作为一个填充位的例子。这可能是一个软件功能的实现,但也可能是一个硬件功能。因此,可能存在用于填充位的其他硬件标志,包括因任何原因而更改读访问的硬件标志。

我们将很难找到这样一个异国情调的机器和实现,但我没有看到任何禁止这一点。如果我错了就纠正我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11994513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档