27

c99でコンパイルされたプロジェクトでインライン関数を定義したいと思います。どうすればいいですか?ヘッダーファイルで関数を宣言し、.cファイルで詳細を指定すると、定義が他のファイルで認識されません。明示的な関数をヘッダーファイルに入れると、それを使用するすべての.oファイルに定義のコピーがあるため、リンカーで「複数の定義」エラーが発生するため、問題が発生します。

私がやろうとしていることは次のようなものです:

header.h
inline void func()
{
    do things...
}


lib1.c
#include "header.h"
...

lib2.c
#include "header.h"

lib1.oとlib2.oの両方を使用するユーティリティを使用

4

3 に答える 3

29

残念ながら、すべてのコンパイラが C99 に完全に準拠していると主張していても、その時点で完全に準拠しているわけではありません。

これを行うための準拠した方法は次のとおりです。

// header file. an inline definition alone is
// not supposed to generate an external symbol
inline void toto(void) {
  // do something
}

// in one .c file, force the creation of an
// external symbol
extern inline void toto(void);

たとえば、gcc の新しいバージョンは、それで問題なく動作します。

次のようなものを定義することにより、他のコンパイラ(プリテンダー)でそれを回避することができます

#ifdef PRETENDER
# define inlDec static
# define inlIns static
#else
# define inlDec 
# define inlIns extern
#endif
// header file. an inline declaration alone is
// not supposed to generate an external symbol
inlDec inline void toto(void) {
  // do something
}

// in one .c file, force the creation of an
// external symbol
inlIns inline void toto(void);

編集:

-std=c99私が知っているC99 サポート (通常は option ) を備えたコンパイラ

  • gcc (バージョン >= 4.3 IIRC) は正しいinlineモデルを実装します
  • pccも正しい
  • ggc < 4.3 では、正しいモデルを実装するための特別なオプションが必要です。そうしないと、注意しないと複数のシンボルが定義される独自のモデルが使用されます。
  • 特別な注意を払わなければ、icc はすべてのユニットでシンボルを出力するだけです。しかし、これらのシンボルは「弱い」シンボルであるため、競合は発生しません。彼らはあなたのコードを爆破するだけです。
  • opencc、AFAIR、古い gcc 固有のモデルに従います
  • 宣言があり、1 つのコンパイル単位で関数ポインターを使用しない限り、 clang はinline関数のシンボルをまったく出力しません。extern
  • tcc はinlineキーワードを無視します
于 2011-03-08T07:22:12.397 に答える
5

単独で使用する場合、C99 では、使用されinlineているのと同じ変換単位で関数を定義する必要があります (したがって、lib1.c で使用する場合は、lib1.c で定義する必要があります)。

メソッドを次のように宣言することもできますstatic inline(そして、2 つのソース ファイル間で共有されるヘッダー ファイルに定義を配置します)。これにより、複数定義の問題が回避され、コンパイラはファイルが使用されているすべての翻訳単位でファイルをインライン化できます (1 つの翻訳単位で関数を宣言するだけでは、実行できる場合とできない場合があります)。

参照: http://www.greenend.org.uk/rjk/2003/03/inline.html

于 2011-03-08T07:06:04.100 に答える
-1

ヘッダーファイル内で関数を定義および宣言するときにインラインワードを使用する必要はないと思います。コンパイラは通常、長すぎる場合を除き、デフォルトでインラインとして扱います。その場合、それを処理するのに十分スマートです。通常の機能として。

複数の定義は、ヘッダー ファイルにインクルード ガードがないことが原因である可能性があると思います。

ヘッダーで次のようなものを使用する必要があります。

#ifndef HEADERNAME_H
#define HEADERNAME_H

void func()
{
    // do things...
}

#endif
于 2011-03-08T07:04:13.497 に答える