3.19 名前空間
C 言語には「名前空間」というものはない。そもそも C 言語ができたのは Unix OS の開発時で、その当時は「名前空間」という概念はなかったと思われる。
しかし、規模の大きな開発には名前空間がないと名前の衝突が発生する。これを避けるためグローバルな関数名や変数名にはプリフィックスを付けるとよい。例えば、strcmp というのは string.h にある標準関数であるので、同じ名前は避ける必要がある。 そのような場合、例えばプリフィックスとして “my_” を関数名の頭にかぶせるとよい。つまり my_strcmp() のようにすれば、名前の衝突を避けることができる。
そのモジュール (C ソースファイル) の外から参照させる必要のない関数や変数には static を付けるとよい。static を付けるとそのモジュールの外部からは不可視になる。 その場合にでも標準関数と同じ名前を付けるのを避けないと、その関数が含まれるヘッダファイルをインクルードできなくなる。
次に main 関数を含む main.c と main.c から参照される関数や変数のアクセス性についての例を示す。
main.c
#include <stdio.h>
#include "mod1.h"
// extern const char* modname;
extern const char* filename;
void main() {
const char* name = getModuleName();
printf("name = %s\n", name);
// printf("modname = %s\n", modname); // modname は static なので外部参照ができずリンクエラーになる。
printf("filename = %s\n", filename);
// const char* fname = getFileName(); // getFileName() は static なので外部参照ができずリンクエラーになる。
// printf("fname = %s\n", fname);
}
mod1.h
/* mod1.h */
const char* getModuleName();
static const char* getFileName();
// int atoi(char*);
mod1.c
#include <stdlib.h>
// modname は main.c からは参照できない。
static const char* modname = "mod1";
// static がないので main.c から参照できる。
const char* filename = "mod1.c";
// main.c から参照可能
const char* getModuleName() {
return modname;
}
/* この関数は stdlib.h の atoi() と競合するのでエラーになる。*/
// int atoi(char* s) {
// return 0;
//}
// static が付いているので main.c から参照できない。
static const char* getFileName() {
return filename;
}