Looking at nginx's code I see that pretty much everything is prefixed with ngx_
.
Files:
ngx_list.c
ngx_list.h
ngx_log.c
ngx_log.h
Code:
ngx_log_t *ngx_log_init(u_char *prefix);
void ngx_cdecl ngx_log_abort(ngx_err_t err, const char *fmt, ...);
void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...);
LuaJIT is pretty much the same thing but with lj_
.
Files:
lj_alloc.c
lj_alloc.h
lj_api.c
lj_arch.h
Code:
LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);
LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);
Other project's do the same thing, these are just two that come to mind. Why do they do this? If it was the project's public API I would get it as it will be exposed to third party code. But the code I copied is part of the (private) implementation so why namespace it?
I suspect there's no hard-and-fast reason. I suspect it's just something that people (some people) feel more comfortable with. I wouldn't do it myself, but I guess I can see the appeal.
For example, I have a multiprecision arithmetic library I wrote for fun one day. It has functions like mp_add()
, mt_sub()
, etc. And the source for these functions lives in files add.c
and sub.c
.
Now, since all the source code for this library lives in a subdirectory named mp
, I have never been tempted to give the files names like mp_add.c
or mp_sub.c
. That would just be redundant: the names are already in a very real sense mp/add.c
, mp/sub.c
, etc.
But I have to admit that it does feel a teensy bit weird going to a file named add.c
to check on my multiprecision addition code. It's not integer addition code, or fixed-point or rational-number addition code, or general-purpose addition code. It's very specifically multiprecision addition code, and the functions defined within do all have that mp_
prefix. So shouldn't the filename have that prefix, also?
As I said, no, in the end I wouldn't (I didn't) give it that prefix. But as I also said, I guess I can see the appeal.
Addendum: Above I answered about filenames, but you also asked about internal -- "private" -- function names. And those are different; those definitely need a prefix, at least in C.
The issue is that C does not really have any namespace mechanisms. So you almost always have to fake it with project-specific prefixes on all global symbols.
Consider the function ngx_log_abort()
. It's private to nginx; client code wouldn't be calling it. But it's a global function, so if it were just named log_abort
, there would be a pretty high chance of a collision with a completely different function in the the client code (or in some other library code) also named log_abort
.
You may ask, then why is ngx_log_abort
a global function? And of course the answer is that any of the functions making up the nginx library might need to call it, so it pretty much has to be global.
You may ask, then why isn't ngx_log_abort
a file-scope static
function? And the answer there is, that would work if all the source code for the entire nginx library were confined to a single C source file nginx.c
. But the authors probably didn't want to confine themselves that way.
If you want to write a well-encapsulated library in C, you have two choices for your "private" functions:
Make them file-scope static
, and limit yourself to using a single source file for most or all of your library.
Make them truly global, but with uniqueifying prefixes. Also don't put declarations for them in public header files. (That way clients can't call them without cheating.)
In other languages you have other mechanisms for hiding private symbols, but not in C.