c++ - 重构期间结构的聚合初始化是否安全?

标签 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,甚至会更清楚。

我还没有看到有人提到过这一点,但似乎只有在确定永远不会更改数据布局的情况下才能安全地使用这样的聚合初始化。那将是罕见的情况,那么是否存在“永远不要对非同构结构使用聚合初始化”的潜规则?

最佳答案

Is aggregate initialization of struct safe during refactor?

取决于您在此上下文中如何定义“安全”。以及做了什么样的重构。

it seems that my code can silently break ... since now SomeStruct s{1,2}means that x=1, y=2, z=0

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

这是您可以对类进行的较为良性的更改之一。重新排序成员等不同的更改肯定会需要更改相关代码。

it seems that you can only safely use aggregate initialization like this if you are certain that you will never make changes to the layout of the data.

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

或者,如果您不觉得查找和更新聚合初始化有问题。您应该知道,只要您对聚合进行更改,就存在这种可能性。

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

so is there an unspoken rule of "never use aggregate initialization on non homogeneous structs"?

当然,您和我都考虑过异常(exception)情况。此外,同质性和异质性没有区别。

我会反过来说,当设计一个public API 时,你应该考虑类的布局是应该一成不变,还是让成员私有(private)和提供一个构造函数。对于内部 API,如果您可以快速遍历该类的所有使用,则无关紧要。


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

关于c++ - 重构期间结构的聚合初始化是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42666183/

相关文章:

c++ - OpenCV 2.4.3 到 2.4.9 版本变更

c++ - 完美的转发和构造函数

mysql - 尝试在实例的索引中运行随机数,但出现索引超出范围错误

c - 尝试使用 malloc 时出现段错误

c++ - Qt GUI -> 基于代码到基于设计器

python - Python 中的静态代码分析?

visual-studio - Visual Studio - 插件查找/删除死代码?

c++ - Xcode:如何在 i7 上为旧版 Intel 处理器(i5、Core 2 Duo)构建

c++ - 链接器找不到 mathgl 库

Vim:在 C 中,将结构名称突出显示为 cType