C++ C++;未被调用的函数必须存在,否则代码将爆炸

C++ C++;未被调用的函数必须存在,否则代码将爆炸,c++,debugging,C++,Debugging,所以我有一个非常奇怪的问题,如果这个函数在我的代码中不存在,它将无法工作。它可以是任何名称,它必须存在。我的代码中甚至有一个exit(exit\u FALURE)语句,如果存在,它将运行。(请注意,这种情况发生在多台计算机上) 基本上我必须有这样的代码: void dosomething() { Camera dummyCamera; dummyCamera.refreshTransform(0,0); } 但是我可以像这样重命名这个函数,它仍然可以工作 void thisStillW

所以我有一个非常奇怪的问题,如果这个函数在我的代码中不存在,它将无法工作。它可以是任何名称,它必须存在。我的代码中甚至有一个
exit(exit\u FALURE)
语句,如果存在,它将运行。(请注意,这种情况发生在多台计算机上)

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

void dosomething()
{
  Camera dummyCamera;
  dummyCamera.refreshTransform(0,0);
}
但是我可以像这样重命名这个函数,它仍然可以工作

void thisStillWorks()
{
  Camera dummyCamera;
  dummyCamera.refreshTransform(0,0);
}
不改变代码中的任何其他内容。此函数从未被显式调用。但是,如果我将方法体注释掉,则可以在运行时注意到差异

这是一段关于这件怪事的视频

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

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

我的一些猜测

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

  • 如果不是这样,我想你的编译器/链接器有点坏了。尝试从头开始重新编译所有内容(删除所有.o文件)

  • 我可以想象这样一个场景:您的库被动态链接,您通过索引或其他方式调用动态加载的方法

  • 你做到了:

    #define void void myDefaultFunctionNameIamATroll() \/\/
    

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


      基本上取决于代码在内存中的加载方式,无效的指针访问可能会覆盖不同的位置,因此为函数定义正文将更改布局并防止硬崩溃。

      您的
      refreshTransform
      函数是隐式
      内联的
      ,因为它是在
      的正文中定义的

      这意味着,如果有两个不同的编译单元定义了
      void Camera::refreshttransform(float,float)
      的实现,那么除了一个之外,所有编译单元都将被默默地丢弃。如果实现不同,则说明您的程序格式不正确,不需要进行诊断

      简言之,由于包含的顺序头文件、预处理器符号、该函数中调用的函数的公开重写,或递归应用于每个
      内联
      模板
      以及从该函数调用的类内方法和函数的相同错误,有些代码有两种不同的实现

      当您在特定的编译单元中调用它时,其中一些
      内联
      函数被标记为已使用,并且“放弃所有,但只放弃一个”最终会选择一个不同的编译单元

      现在,这也可能是另一个定义规则冲突——某些类型的大小在不同的编译单元中不同,某些变量或常量的值也不同,等等


      要解决此问题,可以停止
      inline
      ing方法。您可以在匿名名称空间中粘贴
      内联
      函数和
      模板
      函数。您可以跟踪有问题的函数在有更改和没有更改的情况下的行为。并递归搜索。

      这种情况确实发生在多台计算机上。这是我正在与一个团队合作的事情。xcode的.o文件将存储在哪里?那么,我最好的选择是内存损坏,并使用valgrind找出哪里出了问题(这在iOS模拟器上很难或不可能做到)。但首先,确保你的团队中没有任何巨魔在某处隐藏了定义。对“#define”和“dummyCamera”以及“refreshTransform”执行项目范围内的全局搜索。在Xcode中,您可以转到“已组织”并单击“删除派生数据”按钮。我刚刚执行了全局搜索,没有定义。@RyandWkins:克隆项目无法立即进行。有些图书馆不见了。(我现在要睡觉了…@RyanDawkins:您可以通过在
      ryanRedneck
      中设置断点来中断调试器吗?也许调用堆栈将阐明如何调用它。@Peterhune我确实尝试了一个断点,但它只是跳过了断点!我想我可以在视频中演示这一点。我将把它添加到main post.ODR冲突中,该调用使被调用的内联函数的实例成为此转换单元中定义的实例?您是否可以创建一个简单的命令行版本的代码,以分析问题所在?您的视频正在使用XCode。在其他环境中会发生这种情况吗?创建一个问题的MCVE,这样我们就可以在不调试整个项目的情况下更容易地看到和查看它,这将是一个更好的问题。