理解令人困惑的 typedef 语法
考虑以下代码片段,
typedef int type;
int main()
{
type *type; // why is it allowed?
type *k ;// which type?
}
我收到错误'k' is not statements in thisscope
。编译器将 type *k
解析为 type*
和 k
之间的乘法。这样的语法是不是很混乱呢?
为什么 C++ 标准允许 type *type
?因为语法是这么说的?为什么?
Consider the following code-snippet
typedef int type;
int main()
{
type *type; // why is it allowed?
type *k ;// which type?
}
I get an error 'k' is not declared in this scope
. The compiler parses type *k
as multiplication between type*
and k
. Isn't this grammar very confusing?
Why is type *type
allowed by the C++ Standard? Because the grammar says so? Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
C++11 3.3.2/1 说:
因此变量名称
type
直到使用类型名称之后才会引入>类型;类型名称是声明符中
type
的唯一可用含义。局部变量名称隐藏了全局类型名称,因此在此选择。 C++11 3.3.10/1 中对此进行了描述:
当然,完全限定的类型名称
::type
仍然可用。C++11 3.3.2/1 says:
So the variable name
type
is not introduced until after the use of the type nametype
; the type name is the only available meaning oftype
during the declarator.The local variable name hides the global type name, so that is chosen here. This is described in C++11 3.3.10/1:
The fully qualified type name,
::type
, is of course still available.问题实际上是关于变量名何时被定义为标识符,并且语言确定它就在代码中声明变量的点之后:
在其他上下文中也有类似的规则,这只是一个问题决定何时声明标识符。还有其他类似的情况,例如在类的初始化列表中:
或者在成员函数定义中的标识符范围中:
至于决定的理由,我不能告诉你,但它是一致且简单的。
The question is actually about when exactly a variable name is defined as an identifier, and the language determines that it is right after the point in code where the variable is declared:
There are similar rules in other contexts, and it is just a matter of deciding when identifiers are declared. There are other similar situations, for example in the initialization list of a class:
Or in the scope of the identifiers in the definition of member functions:
As of the rationale for the decision, I cannot tell you but it is consistent and simple.
这很令人困惑,但这是访问
type
变量的唯一方法。如果你想使用
type
类型,你可以这样做:大多数语法怪物都来自于与 C 的向后兼容性。
It is confusing, but this is the only way to get access to
type
variable.If you want to use
type
type you can do:Most of those grammar monstrosities come from backward compatibility with C.
保持命名空间(不是 C++ 意义上的,而是变量/类型命名空间)分离的基本原理是相当明显的:当您不使用类型名称污染变量命名空间时,typedef 上的代码中断就会减少。
假设预先存在的代码带有名为“employee”的变量。如果变量和 typedef 位于同一命名空间中,则为“typedef struct {}雇员;”会破坏现有代码,需要更改变量名称(这在 IDE 出现之前是一个问题)。但是,如果它们不共享命名空间,则没有问题,并且人们在大型代码库中选择类型名称时可以少担心一个问题。
The rationale of keeping namespaces (not in the C++ sense, but in variable/type namespace) separate is fairly obvious: When you don't pollute the variable namespace with type names, less code breaks on typedef.
Suppose there was pre-existing code with a variable named "employee". If variables and typedefs lived in the same namespace, a "typedef struct {} employee;" would break the existing code, requiring a change of the variable name (which was more of an issue in pre-IDE days). However, if they do not share a namespace, there is no problem and people have one less issue to worry about when choosing type names in large code bases.
我认为这是允许的,可能是因为它为程序员在为其声明的变量选择名称时提供了灵活性。在 C# 中,您可以声明与类型同名的属性:
当我用 C# 编写代码时,我发现此功能非常有用。因为我有更多的名字可供选择。否则,如果我有一个名为
Name
的类型,那么我将无法创建同名的属性,我将被迫选择不同的名称,比如Name_
、_Name
、name
、NAME
等 - 所有这些都不吸引我。至于您的代码,由于在范围内(在声明 object
type
之后),type
已经是一个变量,因此 type< /em> `类型不能直接引用。但我认为这应该可以很好地编译并根据标准:演示: http://ideone.com/chOov
I think it is allowed probably because it provides flexibility for programmers when choosing name for the variables they declare. In C#, you could declare property of same name as the type:
When I code in C#, I find this feature very useful. Because I've more options for names to choose from. Otherwise, if I've a type called
Name
, then I wouldn't be able to create a property of the same name, I would be forced to choose a different name, sayName_
,_Name
,name
,NAME
etc - all of which don't appeal to me.As for your code, since in the scope (after declaration of object
type
),type
is already a variable, the type `type cannot be referred to directly. But I think this should compile fine and according to the Standard:Demo : http://ideone.com/chOov