web-dev-qa-db-ja.com

gcc警告:関数は使用されていますが定義されていません

警告が表示されます:function used but not defined。ヘッダーファイルにstatic __inline__と言うa.hがあります。ヘッダーファイルはa.cに含まれています。ヘッダーファイルにあるすべてのインライン関数を.cファイルに入れたいと思います。次のコードは私の問題のアイデアを与えます。

元のコード:

a.h:

static __inline__ function1(){
    function definition;  
}

私が変更され:
a.h:

static function1();

交流:

#include "a.h"

static function1(){
   function definition;
}

上記を行うと、警告が表示されます。

   warning: function function1 is used but not defined. 

なぜこのような警告が表示されるのか教えていただけますか?警告が表示されないように、すべての__inline__関数を.cに転送したいと思います。

  warning: function1 is could not be inlined, code size may grow.

前もって感謝します

18
thetna

関数を静的であると宣言しました。これは、現在のコンパイルユニット内でのみ表示されることを意味します。言い換えると、実装は_a.c_ファイル内でのみ表示されます。他の.cファイルが関数を認識できるように、_a.h_と_a.c_の両方でstaticキーワードを削除する必要があります。戻り値を指定する必要があります。例: void function1();は、指定しなかった場合は暗黙的にintであるためです。

43
DarkDust

.cファイル内でstaticと宣言された関数は、そのファイル内でのみ表示/使用可能です。それらがそこで使用されていない場合、それらは事実上デッドコードであり、コンパイラはこの事実について警告します。 GCCでは、unused関数属性 を使用してこの警告を抑制することができます。

static int __attribute__((unused)) function1() {
...
}

編集:

一般に、インライン関数に関しては、通常、次のガイドラインに従う必要があります。

  • それらが複数のCファイルで使用されている場合は、それらをstaticと宣言し、インクルードされたヘッダーファイルで定義します。これにより、そのヘッダーを含むすべての.cファイルに、関数の独自のprivate定義を持たせることができ、コンパイラーが関数をインライン化できるようになります。単独のstatic関数prototypesは、複数のソースファイルで使用されるヘッダーファイルではほとんど意味がありません。実際の定義では行方不明です。

  • それらが再利用されることを意図していない場合は、それらが使用されることになっている.cファイルにそれらの定義(および必要に応じてそれらのプロトタイプ)を入れてください。

関数のサイズが原因でGCCが関数をインライン化できないと文句を言う場合:

  • 本当にその関数をインライン化する必要があるかどうかを自問してください-私の経験から、コンパイラは通常最もよく知っています。

  • その関数を本当にインライン化したい場合は、always_inline関数属性 が役立つ場合があります。インライン関数に許可されるサイズを増やすために、デフォルト以外の -finline-limit=n オプションをGCCに提供する必要がある場合もあります。

インライン関数の追加情報とその使用に関するいくつかの考えられる落とし穴については、 this も参照してください。

編集2:

共有ヘッダーファイルでstatic inline関数が定義されていて、それを通常の関数に変換したい場合は、より良いWordがないため、次のようにする必要があります。

  • その関数の存在が意味をなす.cファイルを選択します(つまり、他の関連する関数と一緒に配置します)。

  • 定義からstaticおよびinlineキーワードを削除し、ヘッダーからそのファイルに定義をmove移動します。

  • staticおよびinlineキーワードをプロトタイプから削除し、ヘッダーファイルに配置します。

おめでとうございます。これで、通常の公開機能が利用できるようになりました。

免責事項:すべてのプログラムに対してpublic、多数のファイルに対してプライベートな関数を作成しました。同じ名前の別のパブリックシンボル(変数または関数)がある場合、リンク中にエラーが発生したり、実行時に奇妙な動作が発生したりする可能性があります。あなたは警告されました...

8
thkala

ヘッダーファイルで関数を通常どおり宣言します

a.h

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

void function1(void);

#endif

staticのない単一のコードファイルで関数を定義します

交流

#include "a.h"

void function1(void) {
  /* function definition */
}

ヘッダーを含めた後、他のファイルから関数を呼び出します

紀元前

#include "a.h"

void quux(void) {
  function1(); /* call regular function */
}

以前の方法(staticとヘッダーファイルでの実装)は、そのヘッダーを含む各コードファイルが独自のバージョンの関数を取得したために機能しました。他のすべてのファイル内の同じ名前の他のすべての関数とは異なります(ただし、まったく同じことを行います)。

3
pmg