为什么在类中添加新的成员变量后需要进行重建?
今天早上,在 Visual Studio 2005 中,我尝试向类中添加一个新的 private
成员变量,发现它给我带来了各种奇怪的分段错误等。当我进入调试模式时,我发现我的调试器甚至没有看到新的成员变量,因此它给了我一些奇怪的行为。
它需要“重建全部”才能让我的程序再次工作(并让调试器看到我所做的新成员变量)。 为什么需要全部重建?为什么仅仅进行常规构建还不够?
我已经解决了这个问题,但我觉得更好地理解构建过程会对我将来有所帮助。如果您需要更多信息,请告诉我。
提前致谢!
This morning, in Visual Studio 2005, I tried adding a new private
member variable to a class and found that it was giving me all sorts of weird segmentation faults and the like. When I went into debug mode, I found that my debugger didn't even see the new member variable, and thus it was giving me some strange behavior.
It required a "rebuild all" in order to get my program working again (and to get the debugger to see the new member variables I had made). Why was it necessary to rebuild all? Why was just doing a regular build insufficient?
I already solved the problem, but I feel like I understanding the build process better will help me in the future. Let me know if there's any more information you need.
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您添加或删除类的成员时,您会更改对象的内存布局。如果不重新编译,就会违反 ODR 规则,而分段错误就是由此产生的结果。
至于为什么会发生这种情况,旧代码可能会获取旧大小的内存,然后将该对象(不带新成员)传递给新代码,新代码将访问已分配内存末尾之外的内容以访问新变量。请注意,访问说明符根本不会产生影响,如果它是私有的,则访问字段的可能是类成员函数。
如果您没有将该字段添加到对象的末尾,而是添加到对象的中间,则在访问编译器在较高内存地址中布置的那些字段时,将会看到相同的效果。
您需要使用全部重建功能这一事实表明您的项目的依赖项配置不正确,您应该尽快修复该问题。拥有正确的依赖关系将迫使编译器在需要时进行重建,并且意味着更少的无用调试时间。
When you add or remove members of a class you change the memory layout of the object. If you don't recompile you are breaking the ODR rule, and the segmentation faults are just the effect of that.
As to why that happens, old code might be acquiring memory for the old size, and then passing that object (without the new member) to new code that will access beyond the end of the allocated memory to access the new variable. Note that the access specifier does not affect at all, if it is private it will probably be the class member functions the ones accessing the fields.
If you did not add the field to the end, but rather to the middle of the object, the same effect will be seen while accessing those fields that are laid out by the compiler in the higher memory addresses.
The fact that you needed to use the rebuild all feature is an indication that the dependencies of your project are not correctly configured, and you should fix that as soon as possible. Having the right dependencies will force the compiler into rebuilding when needed, and will mean less useless debugging hours.
一个明显的答案是:“因为 Visual Studio 已损坏,并且无法正确处理依赖项”。但事实上,我认为您没有向我们提供足够的信息来让我能够做出这样的陈述(Visual Studios 确实正确地描述了简单的情况)。
当您添加成员(
private
或public
,这并不重要),尤其是数据成员以及虚拟函数时,您会更改类在内存中的物理布局。所有依赖于该物理布局的代码都必须重新编译。通常,构建系统会自动处理这个问题,但是损坏的 makefile 或系统中的错误很容易意味着它不会。 (正确的答案不是调用重建/清理,而是修复构建系统的问题。)One obvious answer would be: "because Visual Studios is broken, and doesn't handle dependencies correctly". In fact, however, I don't think you've given us enough information for me to be able to make that statement (and Visual Studios does get the simple cases right).
When you add members (
private
orpublic
, it doesn't matter), especially data members, but also virtual functions, you change the physical layout of the class in memory. All code which depends on that physical layout must be recompiled. Normally, the build system takes care of this automatically, but a broken makefile, or a bug in the system, can easily mean that it doesn't. (The correct answer isn't to invoke a rebuild/make clean, but to fix the problem with the build system.)