并不是说我会ever在我的专业工作中编写如下代码,以下代码在c++和c中是合法的并且编译时没有警告:
#include <stdlib.h>
typedef struct foo { int foo; } foo;
foo * alloc_foo () {
return (struct foo*) malloc(sizeof(foo));
}
struct foo * alloc_struct_foo () {
return (foo*) malloc(sizeof(struct foo));
}
foo * make_foo1 (int val) {
foo * foo = alloc_struct_foo ();
foo->foo = 0;
return foo;
}
struct foo * make_foo2 (int val) {
struct foo * foo = alloc_foo();
foo->foo = 0;
return foo;
}
C 标准第 6.2.3 节使这在 C 中合法且明确:
6.2.3 标识符的命名空间
如果特定标识符的多个声明在翻译单元中的任何一点可见,则句法上下文会消除引用不同实体的使用的歧义。因此,不同类别的标识符(标签名称;结构、联合和枚举的标签;结构或联合的成员;以及普通标识符)有单独的名称空间。
请注意,由于标签名称存在于自己的名称空间中,我可以通过使用标签使代码更加混乱foo
某处。
添加以下代码,代码无法编译:
int foo (foo * ptr) {
return ++ptr->foo;
}
那么,有两个问题,一个与 C 和 C++ 相关,另一个与 C++ 相关。
C/C++问题:为什么我不能定义函数foo
?
看来我应该能够定义该函数foo
;函数名和变量名是“普通标识符”。但是如果我添加最后一点代码我会得到error: redefinition of 'foo' as different kind of symbol
.
问题:foo * foo;
完全合法,那为什么不呢int foo (foo*);
legal?
C++ 问题:这在 C++ 中是如何工作的?
“命名空间”的含义在 C++ 中与在 C 中具有相当不同的含义。我在 C++ 标准中找不到任何谈论 C 命名空间概念的内容,这使得上述内容在 C 中合法。
问题:是什么使得这在 C++ 中合法(首选章节)?
foo * foo;
是完全合法的,那么为什么 int 不呢foo (foo*);
legal?
因为已经有一个名为的类型foo
在与您的函数相同的声明上下文中。同一作用域中不能有同名的类型和函数。
这在 C++ 中是如何工作的?
因为您可以在嵌套范围内隐藏名称。当你声明foo * foo
, 首先foo
指类型。第二foo
声明一个变量——此时,类型foo
被隐藏。尝试声明foo * baz
after foo * foo
,它应该失败。
struct foo {};
void test() {
foo * foo; // first `foo` is the type, second `foo` is the variable
foo * baz; // first `foo` is the variable
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)