C ++未被调用的函数必须存在或代码爆炸

时间:2014-12-05 00:45:22

标签: c++ debugging

所以我有这个非常奇怪的问题,如果这个函数在我的代码中不存在它就不会起作用。它可以是任何名称,它必须存在。我的代码中甚至有一个exit(EXIT_FALURE)语句,如果存在,它将会运行。 (注意这发生在多台计算机上)。

基本上我必须有这样的代码:

void dosomething()
{
  Camera dummyCamera;
  dummyCamera.refreshTransform(0,0);
}

但是我可以像这样重命名这个功能,它仍然有效

void thisStillWorks()
{
  Camera dummyCamera;
  dummyCamera.refreshTransform(0,0);
}

不改变代码中的任何其他内容。永远不会明确调用此函数。但是,如果我将方法体注释掉,可以注意到运行时的差异。

这是一个奇怪的事情的视频......

http://youtu.be/PIyGOoMAa6Y

尚未奏效的解决方案: - 清洁数据
- 注释掉代码
- 在代码库中查找#define
- 删除派生数据
- 在函数体中设置断点(只是跳过)

如果您真的很好奇,可以在这里克隆我们的存储库(您需要自己安装依赖项):

https://github.com/fnk0/MarcusGameEngine

3 个答案:

答案 0 :(得分:2)

我的一些猜测。

  • 我最好的猜测是你有内存损坏,你已经用这个函数指针完全巧合地覆盖了一个vtable值。或者采取某种无效跳转,由于不同的指令填充,它会变得可见。要进行调查,请使用valgrind。

  • 如果不是这种情况,我猜你的编译器/链接器有点破碎。尝试从头开始重新编译所有内容(通过删除所有.o文件)。

  • 我可以想象一个场景,你的库动态链接,你通过索引或其他东西调用动态加载的方法。

  • 你做了:

    #define void void myDefaultFunctionNameIamATroll() \/\/
    

答案 1 :(得分:1)

很有可能这是由内存损坏引起的。 Valgrind会帮助你。更改调试/发布模式和编译器优化级别之间的行为是另一种检查方式。

基本上取决于代码如何在内存中加载,无效指针访问可以覆盖不同的位置,因此为函数定义一个主体将改变布局并防止硬崩溃。

答案 2 :(得分:1)

您的refreshTransform函数隐含inline,因为它是在class的正文中定义的。

这意味着如果有两个不同的编译单元定义void Camera::refreshTransform(float, float)的实现,则除静默之外的所有编译单元都将被静默丢弃。如果实现不同,则程序生成错误,无需诊断。

简而言之,由于包含了订单头文件,预处理器符号,在该函数中调用的函数的公开覆盖,或者递归地应用于每个inlinetemplate的相同错误从该函数调用的类方法和函数,有一些代码有两种不同的实现。

当你在那个特定的编译单元中调用它时,某些inline函数被标记为已使用,并且“丢弃除了一个之外的所有”最终会被选中的另一个。

现在,这也可能是其他一个定义规则违规 - 某些类型的大小在不同的编译单元中有所不同,某些变量或常量的值等等。

要解决此问题,您可以停止inline方法。您可以将inline函数和template函数粘贴到匿名名称空间中。您可以跟踪相关功能在有无变化的情况下的行为方式。并递归搜索。