web-dev-qa-db-ja.com

ヘッダーファイルで定義された小さな関数:インラインまたは静的?

.hファイルで定義されている小さな関数がいくつかあります。これは小規模なプロジェクト(現在)であり、宣言と定義が常に変更されるため、宣言と定義を別々にする必要がないようにしたいと思います。多重定義されたシンボルを回避するために、それらをstaticまたはinlineにすることができます。何を優先する必要があり、その理由は何ですか?

ヘッダーで関数を定義することは一般的に悪い習慣であることは知っています。あなたは答えでこの質問が技術的に意味されることを言及する必要はありません。

20
eudoxos

私はstatic inlineを使用しますが、staticも同様に機能します。

externextern inlineは、ヘッダーが複数の翻訳単位に含まれていると複数の外部定義を取得するため、staticstatic inlineおよびinlineを考慮する必要があるため、使用できません。仕様。

ヘプティックは、ほとんどのコンパイラがinlineが指定されているかどうかに関係なく、インライン化のための関数を検討する、つまりinlineの主な影響はリンケージへの影響であると彼の回答で正しく述べています。

ただし、staticの定義には内部リンケージがあるため、staticstatic inlineの間に大きな違いはありません。純粋にスタイル上の理由から、ヘッダーファイルの関数定義にはstatic inlineを好みます(経験則:ヘッダーファイルにはextern宣言、static const変数定義、およびstatic inline関数定義のみを含める必要があります)。

inlineなしでstaticまたはexternを使用すると、インライン定義が生成されます。 6.7.4、§6)

は、トランスレーターが同じ翻訳単位内の関数への呼び出しを実装するために使用できる外部定義の代替手段を提供します。関数の呼び出しでインライン定義を使用するか外部定義を使用するかは指定されていません。

つまり、インライン定義は常に外部定義を伴う必要がありますが、これはあなたが探しているものではありません。

C99インラインセマンティクスの微妙な点に関する詳細情報は、 Clangホームページこの答えC99の根拠(PDF) にあります。

GCCは、-std=c99または-std=gnu99が存在する場合にのみC99セマンティクスを使用することに注意してください...

25
Christoph

質問はC(C++ではない)に関するものなので、inline

  1. "関数の呼び出しが可能な限り高速になる"(ISO9899-1999、6.7.4(5))を希望します。同じ段落では、この提案がどの程度効果的であるかは実装定義であると述べています。言い換えれば、それはほとんどベアリングを持たず、インライン化をまったく意味しません(実際、非インライン化は、命令キャッシュの影響によりかなり高速になる可能性があります)。
  2. extern(ISO9899-1999、6.7.4(6))と組み合わせていくつかの制限と特別なケースがあります。たとえば、外部リンケージがあるinline関数は同じコンパイル単位で定義する必要があります。そしてインライン定義は、エラーなしでextern定義を他の場所に許可します(2つの関数が機能的に同等である必要はなく、どちらが指定されていないかが指定されていないため、これは必ずしも良いことではありませんコンパイラはいつでも使用します!).

Hepticによって提供されるリンカーの影響はC++には必要ですが、Cでは必要ありません(私が知る限り)。 ISO14882、7.1.2(4)の"すべての変換単位で同じアドレスを使用する必要があります"節では、これらは必須です。 C99の同様の条項については知りません。
しかし、まったく異なる言語のCとC++は通常、同じC/C++コンパイラとリンカーを経由するため、とにかくCでも同じように機能します。

だから...どのようにあなたの質問に答えるのですか?適切だと感じた場合はinlineを使用してください。 externの潜在的な落とし穴に注意してください。それ以外の場合は、そのままにして、コンパイラが正しく実行することを信頼してください。

3
Damon

私はstatic inlineがインライン化したい関数を実行する方法であり、不要な関数はstaticだけだと思います。

静的は可視性を示しますが、inlineは標準(C99)の可視性についてあいまいです。とにかく、それはその目的ではありません:inlineは関数をインライン化するためのものであり、したがって、望ましくない可能性のある観点からの副作用があります。

0
m0skit0