查看nginx的代码,我发现几乎所有内容都以ngx_
为前缀。
文件:
ngx_list.c
ngx_list.h
ngx_log.c
ngx_log.h
代码:
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与lj_
几乎相同。
文件:
lj_alloc.c
lj_alloc.h
lj_api.c
lj_arch.h
代码:
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);
其他项目也做同样的事情,这些只是我想到的两个。他们为什么这样做呢?如果它是项目的公共API,那么我会得到它,因为它将暴露给第三方代码。但是我复制的代码是(私有)实现的一部分,那么为什么要为其命名空间?
答案 0 :(得分:3)
我怀疑没有坚定的理由。我怀疑这只是人们(某些人)感到更舒服的事情。我本人不会这样做,但我想我可以看到这种吸引力。
例如,有一个我为娱乐而编写的多精度算术库。它具有mp_add()
,mt_sub()
等功能。这些功能的源代码位于文件add.c
和sub.c
中。
现在,由于该库的所有源代码都位于名为mp
的子目录中,所以我从来没有想过要给文件名提供诸如mp_add.c
或mp_sub.c
之类的文件。那将是多余的:名称已经是非常真实的mp/add.c
,mp/sub.c
等。
但是我不得不承认,进入名为add.c
的文件来检查我的 multiprecision 附加代码确实有点古怪。它不是整数加法码,也不是定点或有理数加法码,也不是通用加法码。这是非常精确的多精度加法代码,并且其中定义的函数都具有mp_
前缀。那么文件名也应该不带有该前缀吗?
正如我所说,不,最后我不会(我没有)给它加上前缀。但是正如我也说的,我想我可以看到这种吸引力。
附录:以上我回答了有关文件名的问题,但您还询问了内部(“私有”)函数的名称。这些是不同的;至少在C中肯定需要前缀。
问题在于 C确实没有任何名称空间机制。因此,几乎总是必须在所有全局符号上使用项目特定的前缀来伪造它。
考虑功能ngx_log_abort()
。它对nginx是私有的;客户端代码不会调用它。但这是一个全局函数,因此如果仅将其命名为log_abort
,则在客户端代码(或某些其他库代码)中也有一个完全不同的函数(也称为{{ 1}}。
您可能会问,为什么log_abort
是全局函数?当然,答案是组成nginx库的任何函数都可能需要调用它,因此它几乎必须是全局的。
您可能会问,为什么ngx_log_abort
不是文件作用域ngx_log_abort
的功能?答案是,如果整个nginx库的所有源代码都限制在一个C源文件static
中,那将是可行的。但是作者可能不想那样限制自己。
如果您想用C编写一个封装良好的库,则您的“私有”函数有两种选择:
使它们成为文件范围nginx.c
,并限制您对大多数或所有库使用单个源文件。
使它们真正具有全局性,但具有唯一的前缀。也不要在公共头文件中放置它们的声明。 (这样客户就不能不作弊就打电话给他们。)
在其他语言中,您还有其他用于隐藏专用符号的机制,但在C语言中则没有。