typedef中synonym的含义

The meaning of synonym in typedef

以下段落摘自[dcl.typedef]:

Within the scope of its declaration, a typedef-name is syntactically equivalent to a keyword and names the type associated with the identifier in the way described in Clause 8. A typedef-name is thus a synonym for another type. A typedef-name does not introduce a new type the way a class declaration (9.1) or enum declaration does.

我们需要的其他相关段落来自[dcl.type]

As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a type-specifier-seq or trailing-type-specifier-seq. The only exceptions to this rule are the following: … long can be combined with long.

在下面的代码中,i1只是long的同义词。

typedef long i1;
typedef long i1 i2;

因此,我希望第二行被理解为typedef long long i2。然而,MSVC2015RC 失败

Error C2146 syntax error: missing ';' before identifier 'i2'

任何人都可以指出标准中使我的期望无效的部分吗?


更新

我的观点是,据我对 [dcl.type] 中语法的理解,

type-specifier:
    trailing-type-specifier
    class-specifier
    enum-specifier
trailing-type-specifier:
    simple-type-specifier
    elaborated-type-specifier
    typename-specifier
    cv-qualifier
type-specifier-seq:
    type-specifier attribute-specifier-seq opt
    type-specifier type-specifier-seq
trailing-type-specifier-seq:
    trailing-type-specifier attribute-specifier-seq opt
    trailing-type-specifier trailing-type-specifier-seq

a decl-specifier-seq 确实允许一系列类型说明符,只要它们满足组合规则。在我看来,类型与类型说明符不同,即使类型是由类型说明符指定的;-)

AFAIK,没有语法规则表明 long T 是一次有效类型 T 是有效类型。 (但是 限定符 有一些相关规则,例如 volatileconst

换句话说long long应该几乎被看作是一个"multi-word keyword"(但是C&C++标准化委员会非常不愿意引入新的关键字) .

因此,我认为以下内容无效

 // probably invalid
 typedef int fooT;
 unsigned fooT barv;

[dcl.type] 的第 2 段有 longshortsigned、[=15 的规则=]、constvolatile.

As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a type-specifier-seq or trailing-type-specifier-seq. The only exceptions to this rule are the following:

  • const can be combined with any type specifier except itself.

  • volatile can be combined with any type specifier except itself.

  • signed or unsigned can be combined with char, long, short, or int.

  • short or long can be combined with int.

  • long can be combined with double.

  • long can be combined with long.

因此

typedef long i1;
typedef const i1 i2;

是有效的,因为 const 可以与任何类型说明符结合使用,而

typedef long i1;
typedef long i1 i2;

不是,因为 i1long 的名称,但它不是说明符 long 本身。

i1 在您的示例中可能在句法上等同于关键字,但它不在允许与 long 组合的说明符中。这是一个不同的关键字,因此与 long 组合的规则不适用于它。

好的,我来回答

首先,看这个:

a typedef-name is syntactically equivalent to a keyword

这仅表示 typedef 名称遵循关键字语法。这并不意味着 typedef-name 等同于任何特定的关键字。它就像一个新的、独特的关键字。

然后我们有,

A typedef-name is thus a synonym for another type.

那么,给定 typedef long i1;,这个 "another type" 是什么?它是 long int,而不仅仅是 long

另外,什么是"type"?至少,类型说明符不是类型。类型说明符 long 表示类型 "long int"(参见 n3337 的 Table 10 或 n4296 的 Table 9)。

我将在此处复制我的评论:

i1 is a synonym for the type that is long int. It is not a synonym for the keyword long. Otherwise you could also say i1 double and get a long double.

虽然也许我应该说,i1 不是 类型说明符 long 的同义词,但它是 类型 long int.

注意引入同义词概念的目的可能会有所帮助。 同义词已添加到 C 中以解决定义结构时的自动引用问题。 例如,在定义用于表示链表中元素的结构类型时,您可能希望将其定义如下:

typedef struct {
    int                     some_data; ///< ...or anything
    linked_list_element_t*  previous_element;
    linked_list_element_t*  next_element;
} linked_list_element_t;

问题当然是类型“linked_list_element_t”仅在 typedef struct 语句之后定义,因此不能在[]中使用 typedef struct 语句。 您当然可以使用通用的 void* 指针,但这不是好的做法,并且 previous_element 和 next_element 成员可以初始化为指向任何东西。

您需要在类型定义中引用类型。输入同义词:

typedef struct lle_t {
    int     some_data;
    lle_t*  previous_element;
    lle_t*  next_element;
} linked_list_element_t;

在这个俗气的例子中,代码从此仅使用 linked_list_element_t 来引用类型。