拥有多个常量限定符是否合法?[复制]

Is it legal to have multiple const qualifiers? [duplicate]

提问人:Yksisarvinen 提问时间:2/26/2021 更新时间:3/4/2021 访问量:547

问:

由于一些关于放置的讨论,我开始怀疑是否可以对同一类型有多个限定符:constconst

#include <iostream>

int main()
{
    const const int a = 5;
    std::cout << a;
}

别担心,我不会写这样的代码

事实证明,clang 和 MSVC 接受带有警告的代码,但 GCC 拒绝它: https://godbolt.org/z/TdYnvc

哪个编译器是正确的?

C++ 语言律师

评论

3赞 Richard Critten 2/26/2021
我最喜欢的一个是const int const * const pi = nullptr;
0赞 Eljay 2/26/2021
clang++ -Werror foo.cpp如果您希望警告是错误。
2赞 eerorika 2/26/2021
@RichardCritten并不比这更合法。const int constconst const int
0赞 Language Lawyer 2/26/2021
回答为什么这个 const const const 声明有效
0赞 xmh0511 3/4/2021
每个 decl-specifier 在完整的 decl-specifier-seq最多应出现一次,但 long 可以出现两次。

答:

15赞 songyuanyao 2/26/2021 #1

我认为这是不恰当的。[dcl.类型]/2

作为一般规则,最多允许一个定义类型说明符 声明或定义类型说明符序列的完整 decl-specifier-seq,并且最多允许一个类型说明符类型说明符序列中。此规则的唯一例外是 以后:

  • const可以与除自身以外的任何类型说明符组合使用。
  • ...

所以不允许从字面上重复.(允许 typedefs 引入的 PS 冗余 cv-qualifications,但将被忽略)。constconst const int a = 5;

8赞 Bathsheba 2/26/2021 #2

GCC 是正确的。

编译器不应编译代码。原因很明确 [dcl.type.cv]/1

有两个 cv 限定符和 .每个 cv-qualifier 在 cv-qualifier-seq 中最多出现一次。constvolatile

您可以添加到已经存在的类型中(如果无法做到这一点,模板编程将很困难)。但是你不能按照上面的规则写。constconstconst const

评论

0赞 spectras 2/26/2021
顺便说一句,clang 指出“如果我们支持超出标准官方允许范围的扩展,我们会努力在代码中明确指出这一点并发出警告”。我想我们看到了一个偏离严格一致性的例子,正如所承诺的那样,他们确实发出了警告。
12赞 eerorika 2/26/2021 #3

拥有多个常量限定符是否合法?

const const int a = 5;

不。该规则已经被其他很好的答案和另一个答案所涵盖。

请注意,这仅适用于语法,而不适用于一般的类型系统。您可以将 const 应用于 const 类型别名:

using T = const int;
const T a = 5; // OK

多个 cv 限定符以这种方式“折叠”为一个。

哪个编译器是正确的?

在“哪个编译器符合标准”的意义上:所有这些。

编译器不需要拒绝格式错误的程序,也不需要接受它们。由于所有编译器都发出诊断消息,因此它们都符合标准。报价:

[介绍.合规性.一般]

尽管本文档仅陈述了对 C++ 实现的要求,但如果将它们表述为对程序、程序部分或程序执行的要求,则这些要求通常更容易理解。 此类要求具有以下含义:

  • 如果一个程序没有违反 [lex] 到 [thread] 和 [depr] 中的规则,则符合要求的实现应在 [implimits] 中描述的资源限制内接受并正确执行该程序5
  • 如果程序包含违反任何可诊断规则的行为,或者出现本文档中描述为“有条件支持”的构造,而该构造不支持该构造,则符合要求的实现应发出至少一条诊断消息
  • 如果程序包含对规则的违反,而不需要诊断,则本文档不要求与该程序相关的实现。

5)“正确执行”可以包括未定义的行为

故意接受格式错误的程序称为“语言扩展”。

评论

1赞 Yksisarvinen 2/26/2021
感谢您对“拒绝”和“需要诊断”之间区别的详细说明。