c++ 和 c 中的命名空间 [英] Name spaces in c++ and c

查看:27
本文介绍了c++ 和 c 中的命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

并不是说我永远会在我的专业工作中编写如下代码,以下代码是合法的,并且在 c++ 和 c 中编译时没有警告:

Not that I would ever write the code like the following in my professional work, the following code is legal and compiles without warnings in c++ and 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 中合法且明确:

What makes this legal and unambiguous in C is section 6.2.3 of the C standard:

6.2.3 标识符的命名空间
如果在翻译单元中的任何一点都可以看到多个特定标识符的声明,则句法上下文会消除引用不同实体的用法的歧义.因此,对于不同类别的标识符(标签名称;结构、联合和枚举的标签;结构或联合的成员;以及普通标识符)有单独的名称空间.

6.2.3 Name spaces of identifiers
If more than one declaration of a particular identifier is visible at any point in a translation unit, the syntactic context disambiguates uses that refer to different entities. Thus, there are separate name spaces for various categories of identifiers (label names; tags of structures, unions, and enumerations; members of structures or unions; and ordinary identifiers).

请注意,由于标签名称存在于它们自己的名称空间中,我可以通过在某处使用标签 foo 使代码更加模糊.

Note that thanks to label names living in their own name spaces, I could have made the code even more obfuscated by using a label foo somewhere.

添加以下内容,代码无法编译:

Add the following and the code does not compile:

int foo (foo * ptr) {
   return ++ptr->foo;
}   

所以,有两个问题,一个与 C 和 C++ 相关,另一个与 C++ 相关.

So, two questions, one related to C and C++ and the other, C++.

  • C/C++ 问题:为什么我不能定义函数 foo?
    看来我应该能够定义函数 foo;函数名和变量名是普通标识符".但是如果我添加最后一点代码,我会得到 error: redefinition of 'foo' as different kind of symbol.
    问题:foo * foo; 是完全合法的,那么为什么 int foo (foo*); 不合法?

  • C/C++ question: Why can't I define the function foo?
    It seems I should be able to define the function foo; function names and variable names are "ordinary identifiers". But if I add that last little bit of code I get error: redefinition of 'foo' as different kind of symbol.
    Question: foo * foo; is perfectly legal, so why isn't int foo (foo*); legal?

C++ 问题:这在 C++ 中是如何工作的?
命名空间"的含义在 C++ 中与在 C 中具有相当不同的含义. 我在 C++ 标准中找不到任何关于 C 命名空间概念的内容,这就是使上述内容在 C 中合法的原因.
问题:是什么使 C++ 中的此合法(首选章和节)?

C++ question: How does this work at all in C++?
The meaning of "name space" takes on a rather different meaning on in C++ than in C. I can't find anything in the C++ standard that talks about the C concept of name spaces, which is what makes the above legal in C.
Question: What makes this legal in C++ (chapter and verse preferred)?

推荐答案

foo * foo; 是完全合法的,那么为什么 int foo (foo*); 不合法?

foo * foo; is perfectly legal, so why isn't int foo (foo*); legal?

因为在与您的函数相同的声明上下文中已经有一个名为 foo 的类型.同一个作用域中不能有同名的类型和函数.

Because there already is a type named foo in the same declaration context as your function. You cannot have a type and a function of the same name in the same scope.

这在 C++ 中是如何工作的?

How does this work at all in C++?

因为您可以在嵌套作用域中隐藏名称.当你声明 foo * foo 时,第一个 foo 指的是类型.第二个 foo 声明了一个变量——此时 foo 类型是隐藏的.尝试在 foo * foo 之后声明 foo * baz,它应该会失败.

Because you are allowed to hide names in nested scopes. When you declare foo * foo, the first foo refers to the type. The second foo declares a variable -- at that point, the type foo is hidden. Try declaring foo * baz after foo * foo, it should fail.

struct foo {};

void test() {
   foo * foo; // first `foo` is the type, second `foo` is the variable
   foo * baz; // first `foo` is the variable
}

这篇关于c++ 和 c 中的命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆