这种多余的"typedef"是否严格合法?

Lig*_*ica 1 c++ language-lawyer c++11 c++03 c++14

我在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
};
Run Code Online (Sandbox Code Playgroud)

领先typedef是完全没有意义的,不应该存在.
实际上,GCC会发出以下诊断:

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

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

但纯粹出于好奇,我想知道这是严格遵守还是严格错误,并且无法从标准中得知.

这是typedef合法的吗?或者GCC是否宽容?

小智 10

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

一般语法不需要任何一个声明中使用简单的声明,你可能已经知道这一点,因为你不会一直惊讶地看到enum AttributeFormat_e { ... };没有typedef.制作是

simple-declaration:
    decl-specifier-seq opt init-declarator-list opt ;
    attribute-specifier-seq decl-specifier-seq opt init-declarator-list ;

只要没有属性说明符序列存在于一个简单的声明中,初始化声明符列表是可选的.

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

在一个简单声明中,只有在声明一个类(第9节)或枚举(7.2)时,也就是说,当decl-specifier-seq包含一个类说明符时,可以省略可选的init-declarator-list,详细说明-type-specifier,带有类键(9.1)或枚举说明符.[...]

问题中的代码声明了枚举,因此不违反此规则.

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

[...]如果一个存储类说明符出现在DECL说明符-seq的,不可能有typedef在同一说明符DECL说明符-SEQ初始化声明符列表声明不得为空(除对于在命名空间或全局命名空间中声明的匿名联合,应声明static(9.5)).[...]

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

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

根本就没有这样的规则typedef.