【问题标题】:Initialized declarator inside of C++ catch statementC++ catch 语句中的初始化声明器
【发布时间】:2022-01-17 00:38:15
【问题描述】:

你认为在 catch 语句的被捕获声明部分中,初始化的声明符是一个有效的词法结构吗?例如,看看下面的代码:

void func( int = 1 )
{
    try
    {

    }
    catch( int a = 1 )
    {
    }
}

它在最新的 MSVC 17.0.2 下编译良好,但在最新的 GCC 11.2 下编译失败(使用 Godbolt.org 测试)。我想知道答案,以形成关于正确键入 C++ 代码的纯词汇理解。

如果您阅读this cppreference.com article,您会发现它表示函数签名参数的声明应该与 (*) 完全相同,从而使 MSVC C++ 词法分析器具有合法性。

* 实际上并不相同。文本恰好区分了声明器和初始化器部分是分开的。

【问题讨论】:

  • VC 2022 不会编译您的代码。您选择什么标准并不重要(20 年 14 月 17 日)。默认值的意义何在?
  • @LanguageLawyer 我相信这是对declaratorabstract-declarator 描述的转述:“形式参数声明的一部分,与函数参数列表中的相同”。我认为 Tumbleweed 的回答澄清了这里具体称为“相同”的内容。
  • 很抱歉给您带来了困惑。我编辑了问题以消除误传。你们完全正确。没有提到整个类型是相同的,但声明部分恰好不包括定义的可选初始化程序。我预计不是这样。感谢您帮助我正确理解参考。
  • @zdf:你实际上是对的......多么奇怪的情况。我很抱歉我错了......这让我很困惑,上面写着“msvc v19.latest”:godbolt.org/z/xKK4E9zM4
  • @zdf:我已经在他们的官方问题跟踪器上发布了我的问题:developercommunity.visualstudio.com/t/…

标签: c++ syntax language-lawyer lexer


【解决方案1】:

没有。无效。

catch 子句的语法指定type-specifier-seq declarator。其中的declarator 部分不包括初始化程序。将此与函数参数的语法进行比较,确实允许初始化器:

attr(optional) decl-specifier-seq declarator = initializer

【讨论】:

  • 感谢您这么快回答。你得到了我接受的答案标签,因为你是最快的!
  • @rplgn 这完全取决于您,但总的来说,最好将对您最有帮助的答案标记为已接受,而不是发布在最快的。
【解决方案2】:

首先: 不,文章没有说它允许在 catch 语句中使用初始化程序。

上面说要参考功能说明

  • type-specifier-seq
  • declarator
  • abstract-declarator

或者initializer 是一个不同的元素。

第二:

catch 语句中的初始化程序毫无意义,因为实际进入 catch 语句需要一个值。这意味着永远不会使用初始化器值,并且会危及程序流程,因为初始化可能会引发一个充其量终止的异常。

MSVC 可能会出于毫无意义而容忍它,因为它不会影响程序

【讨论】:

  • 你是对的!正如en.cppreference.com/w/cpp/language/function 所指出的,“初始化程序”有不同的产生方式。我有点困惑,所以我提出了这个问题。非常感谢您向我澄清这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-20
  • 2010-12-03
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多