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.