ライブラリを書いていて、自分用に書いたユーティリティ関数がたくさんあるとしましょう。もちろん、これらの関数に外部リンケージを持たせて、ライブラリ ユーザーが混同しないようにする必要はありません (ほとんどの場合、関数の存在を外の世界に伝えないためです)。
一方、これらの関数は異なる翻訳単位で使用される可能性があるため、内部で共有する必要があります。
例を挙げましょう。いくつかのことを行うライブラリがあり、さまざまなソースファイルで必要になる場合があるためcopy_file
、create_directory
それらをユーティリティ関数として実装します。
同じ名前の関数があるためにライブラリのユーザーが誤ってリンケージ エラーにならないようにするために、次の解決策を考えることができます。
- ひどい方法:関数を使用するすべてのファイルに関数をコピーして貼り付け、
static
宣言に追加します。 - 良い方法ではありません: それらをマクロとして記述します。私はマクロが好きですが、これはここではありません。
- ユーザーが同じ名前を作成する可能性が十分に小さくなるように、奇妙な名前を付けます。これは機能するかもしれませんが、それらを使用するコードは非常に見苦しくなります。
- 私が現在行っていること:
static
内部utils.h
ファイルに関数として記述し、そのファイルをソース ファイルに含めます。
最後のオプションは、1 つの問題があることを除けば、ほぼ問題なく動作します。関数の 1 つを使用しない場合、少なくとも警告が表示されます (関数は static として宣言されていますが、使用されていません)。私を狂ったと呼んでください、しかし私は自分のコードの警告を自由に保ちます。
私がやったのは、次のようなものでした。
ユーティリティ.h:
...
#ifdef USE_COPY_FILE
static int copy_file(/* args */)
{...}
#endif
#ifdef USE_CREATE_DIR
static int create_dir(/* args */)
{...}
#endif
...
file1.c:
#define USE_COPY_FILE
#define USE_CREATE_DIR
#include "utils.h"
/* use both functions */
file2.c
#define USE_COPY_FILE
#include "utils.h
/* use only copy_file */
ただし、この方法の問題点は、ユーティリティが導入されるにつれて見苦しくなることです。このような関数が 10 個あると想像してみてください。これらの関数が 7~8 個必要な場合は、インクルードの前に 7~8 行の定義が必要です!
もちろん、別の方法としてDONT_USE_*
、関数を除外するタイプのマクロを使用することもできますが、その場合も、これらのユーティリティ関数をほとんど使用しないファイルに対して多くの定義が必要になります。
どう見てもエレガントじゃない。
私の質問は、どうすれば自分のライブラリの内部にある関数を複数の翻訳単位で使用し、外部リンケージを避けることができるでしょうか?