gpt4 book ai didi

c++ - 在头文件中定义的 c++ 枚举末尾添加一个值会强制重新编译吗?

转载 作者:可可西里 更新时间:2023-11-01 18:36:43 36 4
gpt4 key购买 nike

背景

有一个复杂的系统,里面有几个库和应用程序,几乎每个项目都依赖于一个头文件(例如 foo.h),它定义了一个枚举(#included 在几个 cpp 文件中)。该设计远非理想(但与往常一样,它是一个遗留系统)。

遗憾的是,foo.h 经常变化。

先决条件

假设我们可以保证 foo.h 将被更新:只在末尾添加元素,而不删除现有值或重新定义它们。

问题

这样的修改需要重新编译所有包含header的代码吗?我知道这是类的一个常见问题(通常删除未使用的变量会更改内存布局并最终导致核心转储)。我怀疑枚举也可能出现类似情况,在正常情况下我肯定会重新编译所有内容。目前的情况在所有代码库中引入了一种刚性,这极大地影响了系统的发展方式。

我想知道我是否“必须”重新编译。此信息可用于设计重构策略。

注意

我看过this question ,但我认为它实际上并没有回答我的问题。

最佳答案

默认答案是:如果您的翻译单元(= 预处理源文件)的内容发生变化,您必须重新编译它以使其目标文件与其源形式保持同步。

头文件中的更改 #include d 导致翻译单元的预处理源发生变化,因此必须重新编译才能完全同步。所以从这个角度来看,头文件的变化需要重新编译。


然而,这是最保守的做法。 (如果任何更棘手的方法出现任何问题,您应该回过头来)。实际上,如果您所做的只是将枚举器添加到枚举中,您可能不需要重新编译。

如果你引入一个新的枚举器e42进入标题,但实际上并不在文件 x.cpp 的任何地方使用它,很可能是从 x.cpp 生成的目标文件与 e42 defined 将与从 x.cpp 生成的对象文件 100% 相同没有e42定义。所以从这个角度来看,重新编译是没有意义的。理想情况下,如果生成的目标文件与更改前的目标文件不同,您只想重新编译源文件。

假设您不在文件中使用新的枚举器,那么几乎唯一可以强制更改目标文件的是:枚举类型的大小可以更改。如果您的最大枚举器值是 2147483647,并且您添加了一个新的,则枚举本身的大小很可能会从 32 位跳到 64 位。

您可以通过使用 C++11 显式指定枚举的基础类型的能力来绕过此限制。确保为您要扩展的枚举指定它。

enum EnumerationBeingExtended : int
// ^^^^^ this part
{
// ... list of enumerators as before
};

如果你像这样固定了枚举大小(实际上是整个底层类型),很可能只包含旧枚举定义的目标文件(没有 e42 的目标文件)将与包含的目标文件一起工作新的(带有 e42 的那个)。

当然,从技术上讲,您将处于格式错误的程序领域,因为该程序将违反单一定义规则(不同的翻译单元对该枚举有不同的定义)。但是,如果您所做的只是使用枚举值,那么您在实践中可能会非常安全。

如果你使用 typeid 等时髦的东西,我会对这个技巧保持警惕关于枚举类型。但是,如果您只是“正常”地使用枚举器和枚举类型本身,那么您应该没问题。

当然,理想情况下,您应该将此枚举隔离到仅包含该枚举的头文件中,并大量记录其预期用途。由于该 header 的更改,您可能还必须在构建系统中实际允许不重建文件。

总而言之:形式上,您将得到一个格式错误的程序。但实际上,您应该是安全的。

关于c++ - 在头文件中定义的 c++ 枚举末尾添加一个值会强制重新编译吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37569720/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com