- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
当我看到以下代码在 g++-4.2 中编译时没有错误或警告时,我感到非常惊讶:
typedef enum test { one };
我的假设是,如果您使用 typedef
关键字,它将需要一个额外的标识符,如:
typedef enum test { one } test;
如前所述,g++-4.2 甚至在没有警告的情况下接受它。 Clang++ 3.0 警告“warning: typedef requires a name”,类似地 Comeau 警告“warning: declaration requires a typedef name”,g++-4.6 通知:“warning : 'typedef' 在此声明中被忽略"。
我无法确定标准中允许这样做的位置,而且我发现有两个编译器警告它是必需,这有点令人困惑,如果typedef-name 是必需的,但不存在?
更新:我使用相同的编译器检查了 C。 Clang 和 Comeau 产生相同的输出,gcc 给出警告:“warning: useless storage class specifier in empty declaration”,这似乎更令人困惑。
更新:我检查了删除枚举的名称,结果是一样的:
typedef enum { one };
与命名结构类似:
typedef struct named { int x };
但不是使用未命名的结构,在这种情况下,代码在 g++ (4.2/4.6) 中被拒绝,并显示“error: missing type-name in typedef-declaration”, gcc (4.2/4.6 ) 给出警告:“警告:未定义实例的未命名结构/union ”,clang++“警告:声明未声明任何内容”,comeau“错误:声明需要一个 typedef 名称"
最佳答案
这是一种允许但没有任何好处的退化语法。大多数现代编译器都会被激怒发出警告。默认情况下,他们可能不会。没有 typedef 名称,关键字 typedef
是多余的;在您的示例中,它完全等同于:
enum test { one };
另一个可能发生的地方是结构:
typedef struct SomeThing { int whatever; };
这相当于:
struct SomeThing { int whatever; };
请注意,typedef
正式(或语法上)是“存储类说明符”,如 static
、extern
、auto
和 注册
.
在 ISO/IEC 9899:1999(即 C 标准)中,我们发现:
§6.7 Declarations
Syntax
declaration:
declaration-specifiers init-declarator-listopt;
declaration-specifiers:
storage-class-specifier declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiersopt
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator
declarator = initializer
并且(根据要求):
§6.7.1 Storage-class specifiers
Syntax
storage-class-specifier:
typedef
extern
static
auto
register
如果您跟踪该语法,则有很多退化的可能性,而您展示的只是众多可能性之一。
C++ 可能有不同的规则。
在 ISO/IEC 14882:1998(原始 C++ 标准)中,我们在第 7.1.1 节“存储类说明符”中发现 C++ 不将 typedef
视为存储类;该列表添加了 mutable
并排除了 typedef
。所以,C++中typedef
的语法规范肯定与C规范不同。
§7 Declarations
声明指定如何解释名称。声明的格式为
declaration-seq:
declaration
declaration-seq declaration
declaration:
block-declaration
function-definition
template-declaration
explicit-instantiation
explicit-specialization
linkage-specification
namespace-definition
block-declaration:
simple-declaration
asm-definition
namespace-alias-definition
using-declaration
using-directive
simple-declaration:
decl-specifier-seqopt init-declarator-listopt ;
...
¶5 If the decl-specifier-seq contains the
typedef
specifier, the declaration is called atypedef
declaration and the name of eachinit-declarator
is declared to be a typedef-name, synonymous with its associated type (7.1.3).§7.1 Specifiers [dcl.spec]
The specifiers that can be used in a declaration are
decl-specifier:
storage-class-specifier
type-specifier
function-specifier
friend
typedef
decl-specifier-seq:
decl-specifier-seqopt
decl-specifier
§7.1.1 Storage class specifiers [dcl.stc]
storage-class-specifier:
auto
register
static
extern
mutable
§7.1.2 Function specifiers [dcl.fct.spec]
function-specifier:
inline
virtual
explicit
§7.1.3 The typedef specifier [dcl.typedef]
Declarations containing the decl-specifier
typedef
declare identifiers that can be used later for naming fundamental (3.9.1) or compound (3.9.2) types. Thetypedef
specifier shall not be used in a function-definition (8.4), and it shall not be combined in a decl-specifier-seq with any other kind of specifier except a type-specifier.typedef-name:
identifier
...
In a given scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers. [Example:
typedef struct s { /* ... */ } s;
typedef int I;
typedef int I;
typedef I I;—end example]
§7.1.4 The friend specifier [dcl.friend]
The friend specifier is used to specify access to class members; see 11.4.
§7.1.5 Type specifiers [dcl.type]
type-specifier:
simple-type-specifier
class-specifier
enum-specifier
elaborated-type-specifier
cv-qualifier
由于 §7 ¶5 说 typedef
名称来自 init-declarator 并且 init-declarator-list 被标记为 '< em>opt',我认为这意味着 typedef
名称在 C++ 中可以省略,就像在 C 中一样。
关于c++ - typedef 声明中的 typedef-name 是可选的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6399898/
我正在尝试用 Swift 编写这段 JavaScript 代码:k_combinations 到目前为止,我在 Swift 中有这个: import Foundation import Cocoa e
我是一名优秀的程序员,十分优秀!