Pul*_*nha 82 c namespaces ansi-c
对于大多数语言来说,拥有名称空间似乎是明智之举.但据我所知,ANSI C不支持它.为什么不?有计划将其纳入未来的标准吗?
小智 87
为了完整起见,有几种方法可以实现从命名空间中获得的"好处",在C中.
我最喜欢的方法之一是使用一个结构来容纳一堆方法指针,它们是你的库/ etc的接口.
然后使用此结构的extern实例,在库中初始化指向所有函数.这使您可以在库中保持名称简单而无需踩到客户端命名空间(除了全局范围的外部变量,1个变量与可能数百个方法......)
还有一些额外的维护,但我觉得它很少.
这是一个例子:
/* interface.h */
struct library {
const int some_value;
void (*method1)(void);
void (*method2)(int);
/* ... */
};
extern const struct library Library;
/* interface.h */
/* interface.c */
#include "interface.h"
void method1(void)
{
...
}
void method2(int arg)
{
...
}
const struct library Library = {
.method1 = method1,
.method2 = method2,
.some_value = 36
};
/* end interface.c */
/* client code */
#include "interface.h"
int main(void)
{
Library.method1();
Library.method2(5);
printf("%d\n", Library.some_value);
return 0;
}
/* end */
Run Code Online (Sandbox Code Playgroud)
指某东西的用途 .语法在经典Library_function()Library_some_value方法上创建强关联.但是有一些限制,因为您不能将宏用作函数.
小智 58
C确实有名称空间.一个用于结构标签,另一个用于其他类型.考虑以下定义:
struct foo
{
int a;
};
typedef struct bar
{
int a;
} foo;
Run Code Online (Sandbox Code Playgroud)
第一个是标签 foo,后一个是带有typedef的foo类型.仍然没有发生任何名字冲突.这是因为结构标记和类型(内置类型和typedef'ed类型)位于不同的名称空间中.
C不允许的是按意志创建新的命名空间.在语言被认为是重要的之前,C是标准化的,添加名称空间也会威胁向后兼容性,因为它需要名称修改才能正常工作.我认为这可归因于技术性而非哲学.
编辑:JeremyP幸运地纠正了我并提到了我错过的命名空间.标签和结构/联合成员也有名称空间.
R..*_*R.. 22
C有名称空间.语法是namespace_name.您甚至可以将它们嵌套在一起general_specific_name.如果您希望每次都能在不写出命名空间名称的情况下访问名称,请在头文件中包含相关的预处理器宏,例如
#define myfunction mylib_myfunction
Run Code Online (Sandbox Code Playgroud)
这比名称修改以及某些语言承诺提供名称空间的其他暴行要清晰得多.
Chr*_*oph 10
从历史上看,C编译器不会破坏名称(它们在Windows上执行,但cdecl调用约定的修改只包含下划线前缀).
这使得从其他语言(包括汇编程序)使用C库变得容易,这也是您经常看到extern "C"C++ API包装器的原因之一.
只是历史原因.当时没有人想过有类似命名空间的东西.他们也真的试图保持语言简单.他们将来可能会拥有它
ANSI C 是在命名空间出现之前发明的。
不是答案,而是评论.C没有提供namespace明确定义的方法.它具有可变范围.例如:
int i=10;
struct ex {
int i;
}
void foo() {
int i=0;
}
void bar() {
int i=5;
foo();
printf("my i=%d\n", i);
}
void foobar() {
foo();
bar();
printf("my i=%d\n", i);
}
Run Code Online (Sandbox Code Playgroud)
您可以为变量和函数使用限定名称:
mylib.h
void mylib_init();
void mylib_sayhello();
Run Code Online (Sandbox Code Playgroud)
它与名称空间的唯一区别在于它using无法导入和无法导入from mylib.