这个多余的 "typedef" 严格合法吗?
Is this redundant "typedef" strictly legal?
我在 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: warning: ‘typedef’ was ignored in this declaration
现在,这最终是无害的,尽管它是文件中一种奇怪的半有意义的半 C 声明,否则可能只能被解析为 C++(该声明被发现为 private
中的成员class
).
但纯粹出于好奇,我想知道这是严格合规的还是严格的病式,并且无法从标准中判断出来。
这个前导 typedef
合法吗?还是 GCC 是宽容的?
这是合法的,原因很简单,因为标准中没有任何规定反对它。 typedef
的效果仅定义为它对使用 typedef
说明符定义的名称的影响,因此当没有使用该说明符定义的名称时,行为是明确定义的:typedef
根本就没有效果。
一般来说,语法不需要任何声明符来进行 简单声明 ,您可能已经知道这一点,因为看到 enum AttributeFormat_e { ... };
没有 typedef
。作品是
simple-declaration:
decl-specifier-seqopt init-declarator-listopt ;
attribute-specifier-seq decl-specifier-seqopt init-declarator-list ;
只要 attribute-specifier-seq 出现在 simple-declaration 中,init-声明符列表 是可选的。
typedef int;
将无效,如果没有 typedef
,int;
也会无效,但这是一条不同的规则:那里的规则是声明必须声明某些内容。该规则不适用于您的问题,因为该声明确实声明了某些内容。更准确地说,C++11 [dcl.dcl]p3:
In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (Clause 9) or enumeration (7.2), that is, when the decl-specifier-seq contains either a class-specifier, an elaborated-type-specifier with a class-key (9.1), or an enum-specifier. [...]
问题中的代码声明了一个枚举,所以没有违反这条规则。
static enum E { x };
将无效,但这是另一个不同的规则:C++11 [dcl.stc]p1:
[...] If a storage-class-specifier appears in a decl-specifier-seq, there can be no typedef
specifier in the same decl-specifier-seq and the init-declarator-list of the declaration shall not be empty (except for an anonymous union declared in a named namespace or in the global namespace, which shall be declared static
(9.5)). [...]
const enum E { x };
也是无效的,但这是第三条不同的规则:C++11 [dcl.type.cv]p1:
[...] If a cv-qualifier appears in a decl-specifier-seq, the init-declarator-list of the declaration shall not be empty. [...]
typedef
.
根本就没有这样的规则
我在 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: warning: ‘typedef’ was ignored in this declaration
现在,这最终是无害的,尽管它是文件中一种奇怪的半有意义的半 C 声明,否则可能只能被解析为 C++(该声明被发现为 private
中的成员class
).
但纯粹出于好奇,我想知道这是严格合规的还是严格的病式,并且无法从标准中判断出来。
这个前导 typedef
合法吗?还是 GCC 是宽容的?
这是合法的,原因很简单,因为标准中没有任何规定反对它。 typedef
的效果仅定义为它对使用 typedef
说明符定义的名称的影响,因此当没有使用该说明符定义的名称时,行为是明确定义的:typedef
根本就没有效果。
一般来说,语法不需要任何声明符来进行 简单声明 ,您可能已经知道这一点,因为看到 enum AttributeFormat_e { ... };
没有 typedef
。作品是
simple-declaration:
decl-specifier-seqopt init-declarator-listopt;
attribute-specifier-seq decl-specifier-seqopt init-declarator-list;
只要 attribute-specifier-seq 出现在 simple-declaration 中,init-声明符列表 是可选的。
typedef int;
将无效,如果没有 typedef
,int;
也会无效,但这是一条不同的规则:那里的规则是声明必须声明某些内容。该规则不适用于您的问题,因为该声明确实声明了某些内容。更准确地说,C++11 [dcl.dcl]p3:
In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (Clause 9) or enumeration (7.2), that is, when the decl-specifier-seq contains either a class-specifier, an elaborated-type-specifier with a class-key (9.1), or an enum-specifier. [...]
问题中的代码声明了一个枚举,所以没有违反这条规则。
static enum E { x };
将无效,但这是另一个不同的规则:C++11 [dcl.stc]p1:
[...] If a storage-class-specifier appears in a decl-specifier-seq, there can be no
typedef
specifier in the same decl-specifier-seq and the init-declarator-list of the declaration shall not be empty (except for an anonymous union declared in a named namespace or in the global namespace, which shall be declaredstatic
(9.5)). [...]
const enum E { x };
也是无效的,但这是第三条不同的规则:C++11 [dcl.type.cv]p1:
[...] If a cv-qualifier appears in a decl-specifier-seq, the init-declarator-list of the declaration shall not be empty. [...]
typedef
.