【问题标题】:Is copying partially initialized structures well defined in C?复制部分初始化的结构是否在 C 中定义良好?
【发布时间】:2015-10-16 14:34:53
【问题描述】:

我最近了解到通过简单的构造或赋值复制部分初始化的结构是undefined in C++。在 C 中是否也是如此,或者标准是否保证初始化和赋值的行为类似于 memcpy

typedef struct { int i; int j; } A;

void foo() {
   A x;
   x.i = 0;
   // Leave x.j indeterminate. Is the following well defined?
   A y = x;
   y.j = y.i + 1;
}

【问题讨论】:

  • C 中没有部分初始化的 structs。(想想你的问题的含义。)请注意,x.i = 0; 不是初始化,而是赋值。
  • @Olaf:也许我的措辞不正确。 x.j 至少是未指定的,不是吗?
  • 是的,因为您初始化结构,而是将值分配给单个字段。但是这样的问题很有趣,尽管我不希望在这里有太多惊喜。为什么不对x 使用复合初始化器?
  • @Olaf 我不建议编写这样的代码。我只对 C++ 的语言细节和兼容性问题感兴趣。
  • @precarious:在您的特定示例中,C11 草案标准的Annex J.2: Undefined behavior 就足够了:The value of an object with automatic storage duration is used while it is indeterminate (6.2.4, 6.7.9, 6.8).

标签: c language-lawyer c99 c11


【解决方案1】:

x 没有“部分初始化”,这根本没有初始化。 在 y 的初始化程序中读取 x 会将“不确定的”价值(如果可以这么说的话)传播到 y。如果int 在您的平台上可能有陷阱表示,这已经是一个错误。 但是你没有读到那个不确定的字段y.j,所以那个特定的任务没有问题。

【讨论】:

  • 如果x.j 包含陷阱表示,A y = x; 本身是否会出错?
  • 如果它一个陷阱,是的。但是现在很少有整数陷阱表示的架构,所以这更像是一个理论问题。无论如何,这是理论上的,因为一个好的程序员总是初始化他们的struct变量,不是吗。
  • @JensGustedt:即使 if 存在陷阱表示,复制整个 struct 是否会不只是复制该模式而不是陷阱,除非显式访问复制的字段? IOW:访问包含陷阱表示的整个struct 是否也会陷入陷阱?
  • @Olaf,不,您可以例如 memcpy 它,这与 = 不同。这里的问题是初始化和赋值是递归定义的,初始化/分配各个字段,并且也适用于无地址对象,例如register。然后读取捕获字段,并尝试在其类型中解释它。
  • @JensGustedt:许多类型的结构都包含许多有时相关但有时不相关的字段。要求程序要么花时间填充无意义的字段,要么花更多的时间避免复制无意义的字段,而不是盲目地复制它们,这并没有提高效率。
猜你喜欢
  • 2016-12-11
  • 2019-02-01
  • 2016-09-29
  • 2011-03-11
  • 2013-10-25
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多