【问题标题】:Is this redundant "typedef" strictly legal?这种多余的“typedef”严格合法吗?
【发布时间】:2015-03-15 00:08:05
【问题描述】:

我在 ACE Radius 库的 v0.9.2 中找到了以下声明:

// Types of attribute data
typedef enum AttributeFormat_e
{
    E_ATTR_FORMAT_INTEGER,
    E_ATTR_FORMAT_IP_ADDRESS,
    E_ATTR_FORMAT_STRING,
    E_ATTR_FORMAT_VENDOR_SPECIFIC,
    E_ATTR_FORMAT_USER_PASSWORD,
    E_ATTR_FORMAT_CHAP_PASSWORD
};

前面的typedef 完全没有意义,不应该出现。
事实上,GCC 会发出以下诊断信息:

/usr/include/ace-radius/RadiusAttribute.h:597:警告:此声明中忽略了“typedef”

现在,这最终是无害的,尽管这是文件中的一种奇怪的半有意义的半 C 声明,否则只能被解析为 C++(该声明在 class 中被发现为 private 成员)。

但纯粹出于好奇,我想知道这是否严格合规,或严格不规范,并且无法完全从标准中分辨出来。

这是领先的typedef 合法吗?还是 GCC 允许?

【问题讨论】:

  • C 向后兼容性。
  • @al-Acme:不,仔细看。这不是typedef enum E {} name; ...这是typedef enum E {};
  • 这对我来说似乎不是重复的,OP 似乎知道 C 中 typedef enum 的含义。
  • 也是“C”而不是“C”。

标签: c++ c++11 language-lawyer c++14 c++03


【解决方案1】:

这是合法的,原因很简单,标准中的任何地方都没有禁止它的规则。 typedef 的效果仅定义为它对使用 typedef 说明符定义的名称的影响,因此当没有使用该说明符定义的名称时,行为是明确定义的:typedef 根本没有效果。

一般的语法对于simple-declaration 不需要任何声明符,您可能已经知道这一点,因为如果没有typedef,您看到enum AttributeFormat_e { ... }; 不会感到惊讶。作品是

简单声明
decl-specifier-seqopt init-declarator-listopt ;
attribute-specifier-seq decl-specifier-seqopt init-declarator-list ;

只要 simple-declaration 中没有 attribute-specifier-seqinit-declarator-list 是可选的。

typedef int; 无效,int; 没有typedef 也会无效,但这是一条不同的规则:规则是声明必须声明某些内容。该规则不适用于您的问题,因为该声明确实声明了某些内容。更准确地说,C++11 [dcl.dcl]p3:

simple-declaration 中,可选的 init-declarator-list 只有在声明类(第 9 条)或枚举(7.2)时才能省略,即, 当 decl-specifier-seq 包含一个 class-specifier,一个 elaborated-type-specifier 和一个 class-key (9.1) 或 枚举说明符。 [...]

问题中的代码是声明一个枚举,所以不违反这条规则。

static enum E { x }; 无效,但这是另一个不同的规则:C++11 [dcl.stc]p1:

[...] 如果 storage-class-specifier 出现在 decl-specifier-seq 中,则同一 中不能有 typedef 说明符em>decl-specifier-seq 和声明的 init-declarator-list 不得为空(在命名命名空间或全局命名空间中声明的匿名联合除外,它应声明为static (9.5))。 [...]

const enum E { x }; 也会无效,但这是第三条不同的规则:C++11 [dcl.type.cv]p1:

[...] 如果 cv-qualifier 出现在 decl-specifier-seq 中,则 init-declarator-list声明不得为空。 [...]

typedef 根本没有这样的规则。

【讨论】:

  • 这似乎不是一个好的论点。该标准不是“只要不违法,任何东西都是合法的”,而且您还没有指出 typedef 的特征(或其语法产生的事实)允许发出“目标名称”。我正在寻找比“这只是合法的,嗯?”更具体的东西
  • @LightnessRacesinOrbit 您已经非常清楚语法允许在没有任何声明符的情况下进行声明。这就是没有typedefenum AttributeFormat_e { ... }; 是有效的。但我会详细说明。
  • @LightnessRacesinOrbit 当然,已编辑。这包括它吗?
  • 啊哈!是的,我认为可能是这样。它仍然不是很令人满意,但这是 C++ 的错,而不是你的错。感谢您的宝贵时间
  • @hlide C 和 C++ 都不允许 typedef 与(其他)存储类说明符混合。语法允许,但语义不允许。 C 说“最多可以在声明的声明说明符中给出一个存储类说明符。”而在 C++ 中,typedef 不是存储类说明符,规则写为“typedef 说明符不得与除类型说明符之外的任何其他类型的说明符组合在 decl-specifier-seq 中。”注意:typedef可以extern一起出现,如果后者是链接规范的一部分:extern "C" typedef void f();是有效的。
猜你喜欢
  • 2018-02-22
  • 2021-03-12
  • 1970-01-01
  • 2013-02-06
  • 1970-01-01
  • 2018-12-19
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多