重构期间struct的聚合初始化是否安全?

时间:2017-03-08 08:16:44

标签: c++ struct refactoring type-safety aggregate-initialization

如果我有结构

SomeStruct
{
  double y;
  double x;
};

我在某处初始化它像

SomeStruct s{1,2}; //y=1 x=2

然后,如果我将结构重新排序为

,我的代码似乎可以默默地中断
SomeStruct
{
  double x;
  double y;
  double z;
};

因为现在SomeStruct s{1,2}意味着x = 1,y = 2,z = 0

编辑: 提出的一个论点是构造函数具有相同的问题,这是正确的,但在那里你通常可以看到参数名称和命令 - 如果使用任何现代IDE,则更清楚如此。

我还没有看到有人提过这个,但是如果您确定永远不会对数据布局进行更改,那么您似乎只能安全地使用聚合初始化。那将是罕见的情况,那么是否有一条潜规则“从不在非齐次结构上使用聚合初始化”?

1 个答案:

答案 0 :(得分:0)

  

重构期间struct的聚合初始化是否安全?

取决于您如何定义" safe"在这种背景下。进行了什么样的重构。

  

似乎我的代码可以默默地破解......因为现在SomeStruct s{1,2}意味着x=1, y=2, z=0

哪个可能完全没问题。为什么不应该将z初始化为0?在你知道它代表什么之前,你无法判断它是否已被破坏。

这是您可以对课程进行的更为温和的改变之一。一个不同的变化,例如重新排序成员,更确定地需要更改相关代码。

  

如果您确定永远不会对数据布局进行更改,那么您似乎只能安全地使用此类聚合初始化。

或者,如果预期唯一的更改是新的成员,可以进行值初始化。 (C支持指定的初始化程序,这些程序甚至可以适应成员顺序的变化。不幸的是,我们在C ++中没有它们。)

或者,如果您没有发现查找和更新聚合初始化的问题。每当您对聚合进行更改时,您应该知道存在这种可能性。

但实际上,构造函数确实提供了一种实现防火墙"将用户与成员的更改分离开来。像新成员这样的一些更改可能会提示对构造函数进行更改,但缺少构造函数参数会有助于破坏编译。

  

所以有一个未说明的规则"永远不会在非同构结构上使用聚合初始化"?

当然不是没有你和我考虑过的例外。同样,同质异质性没有区别。

我会以另一种方式翻转视角,并说在设计 public API时,您应该考虑是否应该将类的布局设置为一成不变,或者将成员设置为私有提供构造函数。对于内部API,如果您能够快速完成课程的所有使用,那么这并不重要。

GCC有一个警告选项,可以解决您描述的确切情况:-Wmissing-field-initializers(由-Wextra启用)。如果您提供任何成员初始值设定项,它将生成警告,但不是全部。