9

次の方法で宣言されたクラスがあります。

#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass : public MyOtherClass
{

public:
    MyClass();

    int a() const{ return _a; };
    int b() const{ return _b; };

private:
    int _a;
    int _b;
};

inline bool operator==( const MyClass& lhs, const MyClass& rhs )
{
    return (lhs.a() == rhs.a()) && (lhs.b() == rhs.b());
}

#endif

私の問題は、オーバーロードされたブレークポイントに設定されているブレークポイントがoperator==ヒットしないことです。Visual Studio では、実行がこの関数に決して到達しないことを教えてくれます。比較演算子をオーバーロードするためにこの経験則に従いましたが、それらを非メンバーにすること以外は何も言及していないため、演算子のオーバーロードまたはインライン関数で何かを見逃したかどうかはわかりません。

ブレークポイントがヒットしない理由を誰か教えてもらえますか?

4

3 に答える 3

16

コンパイラがコードをインライン展開しているため、ブレークポイントがヒットすることはありません。そのインライン関数内にブレークポイントを設定することは、数百または数千の「仮想」ブレークポイントを設定することを意味する可能性があります。どのコードがどこにインライン化されているかを追跡することは、IDE が行うにはあまりにも多くの作業であり、その結果、インライン化されません。

この問題を回避するには、デバッグで実行するか (インライン化は発生しないと思います)、関数をインライン化しないでください。

/Od フラグを使用してコンパイルして、インライン化やその他すべての最適化を無効にすることもできます (これはデバッグで行われます)。

/Ob0 フラグを設定すると、インライン化が無効になります。ただし、パフォーマンス上の理由から、これを頻繁に実行しないことをお勧めします。そのため、デバッグで実行することをお勧めします。

于 2012-10-16T09:40:22.550 に答える
4

OPがVSでデバッグモードを使用していると述べたので、これを複製しようとしましたが、複製できます。

1>Remove /ZI flag  (no debug infomration) but set it /Zi instead.
2>Disable /Od flag (so no inline) & set it to /Od2.

このようにして、通常のブレークポイントを追加できますが、実際にはインライン化されているため、インライン関数のブレークポイントに入ることができません。

クリス・ウィルソンさん、あなたのプロジェクトのプロパティに行って、

1>/ZI flag is set.
2>/Od flag is disabled. 

方法がわからない場合は、以下の 2 つの MSDN リンクでこれら 2 つのフラグを確認してください。

http://msdn.microsoft.com/en-us/library/47238hez(v=vs.71).aspx

http://msdn.microsoft.com/en-us/library/958x11bc(v=vs.80).aspx

于 2012-10-16T10:16:57.750 に答える
0

inline関数本体がすべての呼び出しサイトでインライン化されるという意味ではありません。実際には、明示的に定義されていなくても、関数はコンパイラによってインライン化できますinline。また、1 つの関数を 1 つの呼び出しサイトでインライン化し、別の呼び出しサイトで通常どおり呼び出すことができます。このディレクティブは、コンパイラへの単なるヒントです。Visual Studio デバッガーは、インライン関数で正常に動作します。

inlineこの問題はディレクティブが原因ではないと思います。このディレクティブを削除して、デバッガーでコードを実行してみてください。そして、このような場合の単体テストを書くのは非常に便利です。

于 2012-10-16T09:51:19.200 に答える