4

私が望んでいるのは、一部の選択された関数を除いて、関数がインライン化されていないビルド構成です (インライン化されている場合とされていない場合があり、コンパイラ次第です)。

さらに良いのは、ある種の「インライン化レベル」です。関数ごとにそのようなレベルを指定でき、さらにビルド時に最小レベルを指定でき、最小レベルを超える関数のみをインライン化できます。これには標準的な解決策がないことはわかっていますが、コンパイラ固有のハックは大歓迎です。

デバッガーでインライン化されていないほとんどの関数をステップ実行できるようにしたいのですが、一部はパフォーマンス上の理由から、一部は非常に深い呼び出しスタックを回避するために、選択したいくつかをインライン化する必要があります。コードにはかなり厄介なテンプレート メタプログラミングが含まれていますが、その部分はほぼ完了しているので、残りの部分に集中したいと思います。そのため、テンプレート メタプログラムに属する関数をインライン化して、他のインライン関数をインライン化しないと便利です。

このようなことを達成する方法はありますか?

4

2 に答える 2

8

コンパイラによっては、はい。g++ の場合、次のように動作します。

void foo() __attribute__ ((noinline));
void foo() __attribute__ ((always_inline));

MSVC++ の場合:

__declspec(noinline) void foo();
__forceinline void foo();

g++では、定義ではなくプロトタイプにのみ属性を適用する必要があることに注意してください。したがって、関数が定義のみ (別のプロトタイプがない) の場合、属性を適用するためにプロトタイプを作成する必要があります。MSVC にはこの要件がありません。

__forceinline具体的にはいくつかの例外があります。それらを注意深く読んで、特定の状況で効果があるかどうかを確認してください. g++ は属性の例外を文書化していませんalways_inlineが、いくつかのことはすぐにわかります (たとえば、仮想メソッドへの呼び出しのインライン化は、メソッドが静的に呼び出された場合にのみ機能します)。

これをマクロで一般化できます。

#ifdef _MSC_VER
 #define NOINLINE(x) __declspec(noinline) x
 #define INLINE(X) __forceinline x
#else
 #ifdef __GNUC__
  #define NOINLINE(x) x __attribute__ ((noinline))
  #define INLINE(x) x __attribute__ ((always_inline))
 #else
  #error "I don't know how to force inline/noinline on your compiler."
 #endif
#endif

INLINE(void foo());
NOINLINE(void foo());
于 2012-06-12T20:10:00.683 に答える
1

必要な関数のセットがある場合は、いくつかのマクロ (GCC または Clang を想定) をにinlineすることができます。#define__attribute__(__always_inline__)

  1. 関数を常にインライン化する
  2. 技術的な理由でそれが不可能な場合は、コンパイル エラーを発生させます。
于 2012-06-12T20:11:50.903 に答える