- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
背景
有一个复杂的系统,里面有几个库和应用程序,几乎每个项目都依赖于一个头文件(例如 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/
我是一名优秀的程序员,十分优秀!