1

C++11 フラグ (-std=c++11) なしでコンパイルされたライブラリと、-std=c++11 でビルドされたそのライブラリにリンクするアプリケーションがあります。ライブラリ内の関数を呼び出すと、プログラムはライブラリ内でさらに深くクラッシュします。クラッシュが発生する関数 (クラス内のポインターを返す単純な関数) の逆アセンブリは、コールスタックがこのプログラムから発生した場合と、ライブラリのテスト プログラムから発生した場合とでは異なることがわかりました。 C++11 フラグを使用してビルドされていません。

OSはOS X Mountain Lion、コンパイラはClang++です。

C++11 アプリと C++11 以外のライブラリの間に機能がないのはなぜですか? また、異なる生成コードがライブラリ内にあるために逆アセンブリが生成されるのはいつですか?

2 つの異なる分解:

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    
4

1 に答える 1

1

OS X で使用される x86-64 ABI では、関数への最初の引数は で渡され%rdi、関数の戻り値は で渡され%raxます。* したがって、この関数は何らかのデータ構造へのポインターを取り、含まれている 64 ビット値を返します。関数のコンパイル方法に応じて、オフセット 64 または 40 から開始します。

したがって、そのデータ構造を定義するヘッダー ファイルを確認する必要があります。C++ 11としてコンパイルしているかどうかに応じて、データ構造の定義が異なります。#ifdefおそらく、 a の定義が異なることを知っているような、明らかな何かがあるかもしれません。または、タイプが異なるように定義されているメンバーが存在する可能性があります。わからない場合は、質問を編集して、関数に (ポインターによって) 渡されるデータ構造の定義に貼り付けCore::GetPointerます。

于 2012-12-01T05:30:51.703 に答える