2011-02-08 14 views
3

私はC++で作業している大きなアプリケーションを持っており、インライン関数が間違った値を返すクラスがあります。 1つのエントリによってオフセットされているように見えます。ここで不正な結果を返すインライン関数

は、コードが設定されている方法の例です:

class Test 
{ 

private: 
    uint myVal1;  
    uint myVal2; 
    uint myVal3; 
    uint myVal4; 

public: 
    uint myFunct1() const { return myVal1 }; 
    uint myFunct2() const { return myVal2 }; 
}; 

私たちが見ている何myFunct1がmyVal2とmyFunct2はmyVal3を返す返すことです。関数をインライン化しないと、すべてが期待通りに機能します。

これはなぜ起こっているのでしょうか?

ありがとうございます。

+0

私には(コードのどこか他の)初期化されていない変数(ポインタ)のように見えます。 – thbusch

+1

本当に厄介なものを除外しましょう、本当に値が正しく設定されていると思いますか? – Nim

+0

ええ、値が正しく設定されていて、初期化されていない変数ではありません。なぜなら、メンバーのすべてが正しく見えるからです。hファイルはすべて正常に動作します – JumboSmith

答えて

11

(私はあなたが上記の投稿が実際いくつかのヘッダファイルからの断片であることを前提としています。)あなたのプログラム内の別のソースファイルは同様に、異なるメモリレイアウト関連の設定でコンパイルされたときにそのような

物事は一般的に起こりますクラスのパッキングとアラインメントの設定。ヘッダーファイルはこれらの異なる翻訳単位に含まれており、メモリレイアウト設定の相違のために解釈が異なります。

これらの翻訳単位間でTestオブジェクトを渡すと、問題が明らかになります。 1つの翻訳単位では、1つのメモリレイアウトを持つTestオブジェクトが作成され、別の翻訳単位が読み込まれるか、まったく異なるメモリレイアウトが仮定されます。あなたの場合、インライン関数は各翻訳単位で異なって解釈されます。

メンバー関数を非インライン関数として定義すると、定義されているソースファイルに固有のクラスメモリレイアウトが想定されます。これは、カーペットの下の問題を掃除し、物事を「仕事」にします(アクセス機能は今では1つのメモリレイアウトに結びついているからです)。しかし、まだそれは良い状況ではありません。それはまだ道路の下に同様の性質の様々な問題につながる可能性があります。

プログラム内のすべてのソースファイルが、同じクラスのメモリレイアウト設定でコンパイルされていることを確認してください。

P.S. Fredがコメントで指摘したように、翻訳単位間のクラスメモリレイアウトの相違は、ソースファイルが依存するヘッダーファイルを変更した後にソースファイルを再コンパイルするのを忘れてしまうようなものによって引き起こされる可能性があります。

このような問題のもう1つの「一般的な」原因は、プリプロセッサディレクティブ(すなわち、#ifdef/#endifセグメントによってカスタマイズされたクラスレイアウト)に依存するクラス定義です。 #defineヘッダーファイルを含むソースファイルで重要なことを忘れた場合、そのソースファイルのクラスのメモリレイアウトが異なる可能性があります。

+5

これは、TUをコンパイルし、ヘッダーを変更し、2番目のTUをコンパイルし、2つのTUをリンクします(最初のコンパイルを行わずに)。言い換えれば、上の状況と私の状況の両方で、ビルドシステムが台無しになっています。ヘッダーの依存関係を追跡していることを確認してください。 –

+0

最後のパッキングアラインメント値を正しくポップする際の問題があるようです。 – JumboSmith

+0

@ JumboSmith-私は同じ問題を抱えています。どのように解決しましたか? – user1166419

3

インライン関数は、インラインでない関数と同じ結果を持つ必要はありません。したがって、問題は表示されていないコードのどこかにある必要があります。おそらく、魔法のようにプライベートメンバーの価値を設定しているのでしょうか?

+0

私はその問題を考えていません。私が.cppファイルではなく、.hファイルで関数を定義すると、すべてうまくいきます。 – JumboSmith

+2

@ジャンボスミス:しかし、それは違いをもたらすべきではないので、問題はどこか別の場所になければなりません。私はAndreyTの答えは良い手がかりだと思います。 –

関連する問題