C语言命名空间详解
C语言命名空间分析准则:
1、在同一命名空间、相同作用域中,任何名字须具有唯一性
2、每个结构和联合内部都有自己的命名空间(独立于其他空间)
3、结构标签、联合标签、枚举标签共用一个命名空间(独立于其他空间)
4、goto使用的标签名,只要在同一函数内部唯一(独立于其他空间)
5、所有其他情况共用一个命名空间,如变量、所有枚举常量、typedef定义的别名等(独立于其他空间)
6、#define宏有点特殊,宏覆盖所有命名空间,所有和宏同名的在预处理时都会被替换为宏,只要替换后没有语法错误,这种替换就在神不知鬼不觉中进行。
一个能够完整说明问题的例子
#include <malloc.h>
#include <stdio.h>
//可以开关这个宏定义
//并用gcc -E main.c -o main.i来看宏的效果
//#define msg haha
struct msg //【结构标签命名空间】
{
int msg; //【结构内部的命名空间】,只需在结构内部唯一即可
};
union u_msg //【联合标签命名空间】和结构、枚举标签共用一个命名空间,故这里不能再用msg或e_msg
{
int msg; //联合内部的命名空间,只需在联合内部唯一即可
};
//【其他命名空间】
int msg; //这里可以用msg,只要【其他命名空间】中唯一即可
typedef unsigned int uint;
enum e_msg //【枚举标签命名空间】和结构、联合标签共用一个命名空间,故这里不能再用msg或u_msg
{
zero = 0, //枚举常量也属于【其他命名空间】部分
one,
two,
};
void func(void)
{
msg: //【标签名命名空间】,只要在函数内部唯一即可
return;
}
int main(int argc, char *argv[])
{
struct msg //较小作用域覆盖全局作用域的定义
{
char *msg;
}msg;
enum e_msg
{
zero = 0,
one,
five,
};
msg: //标签名命名空间,只要在函数内部唯一即可
return 0;
}
当打开#define msg haha宏定义后,查看经预处理后源码文件main.i最后部分大致如下:
struct haha
{
int haha;
};
union u_msg
{
int haha;
};
int haha;
typedef unsigned int uint;
enum e_msg
{
zero = 0,
one,
two,
};
void func(void)
{
haha:
return;
}
int main(int argc, char *argv[])
{
struct haha
{
char *haha;
}haha;
enum e_msg
{
zero = 0,
one,
five,
};
haha:
return 0;
}
可见预处理器把所有与宏相同的符号都进行了文本替换,只要替换后没有语法错误,就能通过编译。