17

私は自分の小さな C 数学ライブラリを書き直しています。これは最終的にユーザーの静的ライブラリになり、ベクトル数学インターフェイスのインライン化の恩恵を受けたいと考えています。

私は次のものを持っています:

[ mymath.h ]

...
...
extern float clampf( float v, float min, float max );
...
...

[ mymath.c ]

inline float clampf( float v, float min, float max )
{
    if( v < min ) v = min;
    if( v > max ) v = max;

   return v;
}

私のライブラリは静的であり、.h(および.lib) のみをユーザーに提供するつもりなので、clampfコンパイル時に関数はプログラム内でインライン化されますか?

私は正しいことをしていますが、で関数を宣言しextern.hでインライン化してい.cますか?

4

2 に答える 2

19

あなたはそれをほぼ正しいと思います。あなたは実際にそれを後方に持っています。インライン関数の場合、inline定義をヘッダーファイルに、extern宣言をCファイルに配置する必要があります。

// mymath.h
inline float clampf( float v, float min, float max )
{
    if( v < min ) v = min;
    if( v > max ) v = max;

    return v;
}

// mymath.c
#include "mymath.h"
extern float clampf( float v, float min, float max );

定義(フルボディ)をヘッダーファイルに入れる必要があります。これにより、コンパイラーがインライン定義を使用できるように、ヘッダーファイルを含むすべてのファイルでインライン定義を使用できるようになります。

宣言(プロトタイプ)をソースファイルに入れてextern、ライブラリ内の関数のexternバージョンを発行するようにコンパイラに指示する必要があります。これにより、ライブラリ内で非インラインバージョン用の場所が1つ提供されるため、コンパイラは関数をインライン化するか、共通バージョンを使用するかを選択できます。

これは、MSVCコンパイラではうまく機能しない可能性があることに注意してください。MSVCコンパイラは、一般的にCのサポートが非常に貧弱です(C99のサポートはほとんどありません)。GCCの場合、古いバージョンのC99サポートを有効にする必要があります。最新のCコンパイラは、デフォルトでこの構文をサポートしています。

別:

ヘッダーを変更してstatic inlineバージョンを設定できます。

// mymath.h
static inline float clampf(float v, float min, float max)
{
    ...
}

ただし、これは関数の非インラインバージョンを提供しないため、コンパイラは各変換ユニットに対してこの関数のコピーを作成するように強制される場合があります。

ノート:

  1. C99のインライン化ルールは正確には直感的ではありません。記事「Cでのインライン関数」(ミラー)では、それらについて詳しく説明しています。特に、一番下までスキップして、「インライン関数を使用するための戦略」を見てください。GCCはしばらくの間C99メソッドをデフォルトにしているので、私はメソッド#3を好みます。

  2. 技術的には、がデフォルトexternであるため、関数宣言(または定義)を設定する必要はありません。extern強調するためにそこに置きました。

于 2012-04-24T04:21:07.633 に答える
6

static inline.h ファイルのように関数を定義する必要があります。

static inline float clampf( float v, float min, float max )
{
    if( v < min ) v = min;
    if( v > max ) v = max;

    return v;
}

関数は .c ファイルに存在しない必要があります。

コンパイラは、関数をインライン化せず、適切な関数呼び出しにすることを決定する場合があります。したがって、生成されたすべての .o ファイルには、関数のコピーが含まれる場合があります。

于 2012-04-24T04:07:27.363 に答える