问题描述
限时送ChatGPT账号..并不是说我永远会在我的专业工作中编写如下代码,以下代码是合法的,并且在 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;
是完全合法的,那么为什么 intfoo (foo*);
不合法?
foo * foo;
is perfectly legal, so why isn't intfoo (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屋!
更多推荐
[db:关键词]
发布评论