[英]Quadruple “const” in function definition
I am wondering about how C++ uses its const keyword. 我想知道C ++如何使用它的const关键字。
I have the following function definition. 我有以下功能定义。 Which alone looks quite insane, but works just fine.
单独看起来很疯狂,但工作得很好。
const int const * const Get(){ return new int(1); } const
I am aware of what each placement of the const means, this question isn't about the meaning of the placement of the const keyword. 我知道const的每个位置意味着什么,这个问题不是关于const关键字的位置的意义。
I am quite confused by the use of the const keywords, because you can duplicate them. 我对使用const关键字感到困惑,因为你可以复制它们。
const int const const * const Get(){ return new int(1); } const
// or even
const const int const const * const const Get(){ return new int(1); } const const
// or even yet
const const const int const const const * const const const Get(){ return new int(1); } const const const
Why does the language allow you to do this? 为什么语言允许你这样做?
EDIT: This code can be compiled in Visual Studio 2013, Visual C++ compiler. 编辑:此代码可以在Visual Studio 2013,Visual C ++编译器中编译。 I am not sure about the actual name of the compiler.
我不确定编译器的实际名称。
EDIT2: So the answer is that this is against the standard. 编辑2:所以答案是这是违反标准的。 The code only compiles wihout using
/Za
option. 代码只编译wihout使用
/Za
选项。
I am voting to close the question. 我投票结束这个问题。
Explicitly repeating const
in the same type specifier sequence is disallowed in the standard. 标准中不允许在相同类型说明符序列中明确重复
const
。
[dcl.type]/2 (emphasis mine) [dcl.type] / 2(强调我的)
As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a type-specifier-seq or trailing-type-specifier-seq.
作为一般规则,在声明的完整decl-specifier-seq或类型说明符-seq或trailing-type-specifier-seq中最多允许一个类型说明符。
...
...
— const can be combined with any type specifier except itself.
- const可以与除自身之外的任何类型说明符组合使用。
One might think that this is allowed from the following quote (found by @davidhigh): 有人可能会认为这可以从以下引用中获得(由@davidhigh找到):
[dcl.type.cv]/1 [dcl.type.cv] / 1
There are two cv-qualifiers, const and volatile.
有两个cv限定符,const和volatile。 Each cv-qualifier shall appear at most once in a cv-qualifier-seq.
每个cv-qualifier在cv-qualifier-seq中最多只出现一次。 If a cv-qualifier appears in a decl-specifier-seq, the init-declarator-list of the declaration shall not be empty.
如果cv-qualifier出现在decl-specifier-seq中,则声明的init-declarator-list不应为空。 [ Note: 3.9.3 and 8.3.5 describe how cv-qualifiers affect object and function types.
[注意:3.9.3和8.3.5描述了cv限定符如何影响对象和函数类型。 — end note ] Redundant cv-qualifications are ignored .
- 尾注] 多余的cv资格被忽略 。 [ Note: For example, these could be introduced by typedefs.
[注意:例如,这些可以由typedef引入。 — end note ]
- 结束说明]
However, this rule is to allow const
duplications which arise through substitution in templates or typedef
s, not those explicitly typed by the programmer. 但是,此规则允许通过模板或
typedef
的替换产生const
复制,而不是程序员明确键入的复制。
Taking one of your examples: 以你的一个例子为例:
const const int const const * const const Get(){ return new int(1); } const const
The first four const
s all apply to the int
, breaking the rule posted above. 前四个
const
都适用于int
,违反了上面发布的规则。
The next two const
s apply to the pointer and are invalid by the same rule. 接下来的两个
const
适用于指针,并且由同一规则无效。
The final two const
s are not even part of the declaration for Get
. 最后两个
const
甚至不是Get
的声明的一部分。 They will be applied to whatever the parser finds next, becoming invalid by either the same rules as above, or by other C++ syntax rules. 它们将应用于解析器下一步找到的任何内容,通过与上述相同的规则或其他C ++语法规则变为无效。
VS2013 may compile such code using language extensions, but this is not standard behaviour. VS2013可以使用语言扩展编译此类代码,但这不是标准行为。 gcc 5.1.0 and clang 3.5.1 will both refuse to compile your code and both provide a reasonable diagnostic.
gcc 5.1.0和clang 3.5.1都拒绝编译你的代码,并且都提供合理的诊断。
Re 回覆
” Why does the language allow you to do this?"
“为什么语言允许你这样做?”
it doesn't. 它没有。 The code presented is not real code .
提供的代码不是真正的代码 。 Eg
例如
const int const * const Get(){ return new int(1); } const
(the first example) will not compile with any standard-conforming compiler, for two reasons: (第一个示例)不会使用任何符合标准的编译器进行编译,原因有两个:
const
s at the start (for the int
) are not permitted. int
)的多个const
。 const
at the end is a syntax error. const
是语法错误。 Standardeese for the first point: C++11 §7.1.6/2, Standardeese的第一点:C ++11§7.1.6/ 2,
”
const
can be combined with any type specifier except itself.“
const
可以与除自身之外的任何类型说明符组合使用。
Why? 为什么? Because the standard says so.
因为标准是这样说的。 Here is an excerpt from [dcl.type.cv] which states exactly this (emphasis mine) :
这是[dcl.type.cv]的摘录,其中正好说明了这一点(强调我的):
There are two cv-qualifiers, const and volatile.
有两个cv限定符,const和volatile。 Each cv-qualifier shall appear at most once in a cv-qualifier-seq.
每个cv-qualifier在cv-qualifier-seq中最多只出现一次。 If a cv-qualifier appears in a decl-specifier-seq, the init-declarator-list of the declaration shall not be empty.
如果cv-qualifier出现在decl-specifier-seq中,则声明的init-declarator-list不应为空。 [ Note: 3.9.3 and 8.3.5 describe how cv-qualifiers affect object and function types.
[注意:3.9.3和8.3.5描述了cv限定符如何影响对象和函数类型。 — end note ] Redundant cv-qualifications are ignored.
- 尾注] 多余的cv资格被忽略。 [ Note: For example, these could be introduced by typedefs.
[注意:例如,这些可以由typedef引入。 — end note ]
- 结束说明]
This makes sense in templates, for example. 例如,这在模板中很有意义。 If the template parameter is deduced as
const
, it can easily happen that another const is added somewehere. 如果模板参数被推导为
const
,则很容易发生另一个const被添加到某个地方。
EDIT : as noted several times and redundantly, my above answer is misleading in that it does not qualify here. 编辑 :正如多次提到的那样冗余,我的上述答案具有误导性,因为它不符合此处的条件。 It is opposed by the rule in [dcl.type] which explicitly disallows explicitly typed
const
qualifiers (see the fine comment by @TartanLlama in his answer). 它被[dcl.type]中的规则所反对,该规则明确禁止显式类型的
const
限定符(参见@TartanLlama在其答案中的精细注释)。
EDIT 2 : the application of the rule everyone seems to agree on states: first redundant const
s are disallowed, and if they still should somewhere occur they are ignored. 编辑2 :规则的应用每个人似乎都同意状态:第一个冗余
const
是不允许的,如果它们仍然应该在某个地方发生,它们将被忽略。
This, however, requires a priority of the standard quotes. 但是,这需要标准报价的优先级。
Without, one could also think of an order like: first remove redundant const
s, and only then apply the rule that multiple const
s are not allowed (which, of course, would render the latter rule itself redundant). 如果没有,人们也可以想到一个命令:首先删除冗余
const
,然后才应用不允许多个const
的规则(当然,这会使后一个规则本身变得多余)。
In this case, obviously, the quote shows how it is meant to be interpreted. 在这种情况下,显然,引用显示了它是如何被解释的。 But, being pedantic, it does not have to be interpreted like this -- unless there is some form of priority in the standard quotes.
但是,作为迂腐, 它不必被解释为这样 - 除非标准报价中有某种形式的优先权。
This function declaration (and others) 这个函数声明(和其他)
const int const * const Get(){ return new int(1); } const;
will not compile because according to the C++ Standard (7.1.6 Type specifiers, #2) 将无法编译,因为根据C ++标准(7.1.6类型说明符,#2)
— const can be combined with any type specifier except itself .
- const可以与除自身之外的任何类型说明符组合使用。
and (7.1.6.1 The cv-qualifiers) 和(7.1.6.1 cv-qualifiers)
1 There are two cv-qualifiers, const and volatile.
1有两个cv限定符,const和volatile。 Each cv-qualifier shall appear at most once in a cvqualifier- seq.
每个cv-qualifier 最多只能在cvqualifier-seq中出现一次 。
In this declaration for example qualifier const is combined with itself 在此声明中,例如限定符const与其自身组合
const int const * const Get(){ return new int(1); } const;
^^^^^ ^^^^^
Moreover the last qualifier is placed in the wrong place.:) 而且最后一个限定符放在错误的位置。:)
const int const * const Get(){ return new int(1); } const;
^^^^^
At leats there should be 在leats应该有
const int const * const Get() const { return new int(1); };
^^^^^
Or in this declaration (if to place the cv-qualifier sequence correctly) at least cv-qualifier sequence has more than one const qualifier 或者在这个声明中(如果正确放置cv-qualifier序列)至少cv-qualifier序列有多个const限定符
const const int const const * const const Get() const const { return new int(1); };
^^^^^ ^^^^^
Opposite to C++ in C you may combine several qualifiers in a declaration. 与C中的C ++相反,您可以在声明中组合多个限定符。 The redundant qualifiers are simply ignored.
简单地忽略冗余限定符。 For example
例如
const long const long const int const x = 10;
that is equivalent to 这相当于
const long long int x = 10;
However in C++ this declaration will not compile. 但是在C ++中,这个声明不会编译。
Two separate issues. 两个单独的问题。
By default MSVC issues a warning ( C4114 ) for repeated qualifiers rather than an error. 默认情况下,MSVC会针对重复的限定符而不是错误发出警告( C4114 )。 The standard permits this since all that's required is a diagnostic message, and a warning satisfies this requirement.
标准允许这样做,因为所需要的只是一条诊断消息,并且警告满足此要求。
The final const
s compile only when they are actually part of a subsequent declaration. 最后的
const
只在它们实际上是后续声明的一部分时编译。 For instance: 例如:
const const int const const * const const Get(){ return new int(1); } const const int main() {}
This is actually 这实际上是
const const int const const * const const Get(){ return new int(1); } const const int main() {}
which is "OK" modulo the repeated qualifiers part. 这是“OK”模数重复的限定符部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.