当 C++11 应用程序使用非 C++11 库时返回值损坏

Return value corrupt when C++11 application uses non-C++11 library

本文关键字:C++11 返回值 损坏 应用程序      更新时间:2023-10-16

我有一个没有C++11标志(-std=c++11)的库,还有一个链接到该库的应用程序,该库是用-std=c++11构建的。它调用库中的函数,然后程序在库中崩溃得更深。我发现发生崩溃的函数(这只是一个在类中返回指针的简单函数)的反汇编与调用堆栈源自该程序的时间不同,而不是库的测试程序也不是用 C++11 标志构建的。

操作系统是OS X Mountain Lion,编译器是Clang++。

为什么 C++11 应用程序和非 C++11 库之间不起作用,以及当不同的生成代码位于库中并且因此应该相同时何时生成反汇编?

两种不同的反汇编:

TestApplication`Core::GetPointer() const at System.h:xxx:
0x100009690:  pushq  %rbp
0x100009691:  movq   %rsp, %rbp
0x100009694:  movq   %rdi, -8(%rbp)
0x100009698:  movq   -8(%rbp), %rdi
0x10000969c:  movq   64(%rdi), %rax  ;<-------Difference
0x1000096a0:  popq   %rbp
0x1000096a1:  ret    
Lib1Prototype`Core::GetPointer() const at System.h:xxx:
0x100019c10:  pushq  %rbp
0x100019c11:  movq   %rsp, %rbp
0x100019c14:  movq   %rdi, -8(%rbp)
0x100019c18:  movq   -8(%rbp), %rdi
0x100019c1c:  movq   40(%rdi), %rax  ;<------Difference
0x100019c20:  popq   %rbp
0x100019c21:  ret    

在 OS X 使用的 x86-64 ABI 中,函数的第一个参数以 %rdi 传递,函数的返回值以 %rax 传递。 因此,此函数获取指向某个数据结构的指针,并返回从偏移量 64 或 40 开始包含的 64 位值,具体取决于函数的编译方式。

因此,您需要查看定义该数据结构的头文件。 它以不同的方式定义数据结构,具体取决于您是否编译为 C++11。 也许有一些显而易见的东西,比如你知道#ifdef有不同的定义。 或者,也许有一个成员的类型定义不同。 如果您无法弄清楚,请编辑您的问题并粘贴(通过指针)传递给 Core::GetPointer 函数的数据结构的定义。