【问题标题】:Is "typedef" in between the type and the alias standard-conformant?“typedef”在类型和别名标准符合之间吗?
【发布时间】:2016-05-15 16:49:32
【问题描述】:

我偶然发现了一些代码,其中 typedef 关键字位于类型和别名之间,例如 in

int typedef INT;

它在 gcc 和 clang (live example) 中编译。我对标准语的理解不是很好。所以我的问题是:这个标准符合吗?我可以依靠编译器来支持它吗?

【问题讨论】:

  • @DanielA.White:C 或 C++ 标准以易读性着称。
  • @DanielA.White 该标准并非意味着可读。它应该是精确的
  • @JameyD 这并没有真正的帮助。困难在于解释这段文字。
  • @DanielA.White 我还是不明白。问题显然是这是否符合标准,而不是它是否比其他形式更具可读性(无论如何这可能是题外话)。
  • 英语不是最精确的语言,我们看到这里失败了两次。很难解释其中所写的标准,也很难解释在讨论标准的 cmets 中使用标准一词。人们几乎可以看到巨蟒素描或方丈和科斯特洛的玩笑。

标签: c++ c language-lawyer typedef


【解决方案1】:

typedef 关键字在 C 中被归类为存储类说明符,尽管标准明确指出这是为了方便表达正式语言语法。尽管如此,typedef 可以出现在与任何其他存储类说明符(例如 externstatic)完全相同的位置。 [C2011, 6.7.1/5]

事实上,该语法允许存储类说明符与类型说明符、类型限定符和其他“声明说明符”在声明中混合使用。 [C2011, 6.7/1, 6.7/6]

因此,是的,将 typedef 关键字放在类型名称之后是有效的,如您的示例所示。

【讨论】:

    【解决方案2】:

    TL/DR 版本

    是的,int typedef INT 符合要求。

    詹姆斯米切纳版本

    C 声明语法(C 2011 online draft):

    6.7 声明

    语法

    1    <em>declaration</em>:
    <em>declaration-specifiers init-declarator-list<sub>opt</sub></em> ;
    <em>static_assert-declaration</em>

    <em>declaration-specifiers</em>:
    <em>storage-class-specifier declaration-specifiers<sub>opt</sub></em>
    <em>type-specifier declaration-specifiers<sub>opt</sub></em>
    <em>type-qualifier declaration-specifiers<sub>opt</sub></em>
    <em>function-specifier declaration-specifiers<sub>opt</sub></em>
    <em>alignment-specifier declaration-specifiers<sub>opt</sub></em>
    ...

    这就是说,在单个声明中,您可以拥有一个或多个声明说明符的序列,其中每个声明说明符都可以是存储类说明符(autoexternstatictypedef)、类型说明符(intfloatchar 等)、类型限定符(constrestrictvolatile 等)、a函数说明符 (inline) 或对齐说明符。

    各种说明符出现的顺序无关紧要; static const short int x; 可以写成 int static short const xint short const static x 等。作为实践,大多数人将存储类说明符放在首位,然后是任何函数或对齐说明符(如果需要),然后是任何类型限定符,然后类型说明符,所以static const short int x大多数 人编写该声明的方式。

    这种语法允许我们编写long doublelong longunsigned long int等类型。

    请注意,虽然 语法 允许任意(和任意长)类型说明符序列,但有一条语义规则只允许相对较少的序列。例如,您不能写short short short short xlong long long double y。只允许以下序列:

    约束

    2    每个声明的声明说明符中应至少给出一个类型说明符, 并在每个结构声明和类型名称的说明符限定符列表中。每个列表 类型说明符应为以下多重集之一(用逗号分隔,当有 每个项目不止一个多重集);类型说明符可以以任何顺序出现,可能 与其他声明说明符混合使用。
    void
    char
    signed char
    unsigned char
    short, signed short, short int, or signed short int
    unsigned short, or unsigned short int
    int, signed, or signed int
    unsigned, or unsigned int
    long, signed long, long int, or signed long int
    unsigned long, or unsigned long int
    long long, signed long long, long long int, or
    signed long long int
    unsigned long long, or unsigned long long int
    float
    double
    long double
    _Bool
    float _Complex
    double _Complex
    long double _Complex
    — 原子类型说明符
    — 结构或联合说明符
    — 枚举说明符
    — typedef 名称

    附录

    正如 Keith 在下面的评论中指出的那样,该语言的未来版本可能会将存储类说明符限制在声明的开头,因此 int typedef INT 在未来的编译器下可能不合法。

    【讨论】:

    • 是的——但是C standard 6.11.5(未来语言方向)说:“存储类说明符在声明中的声明说明符开头以外的位置是过时的功能。”,因此至少在原则上未来的 C 标准可能不允许int typedef INT;。随时将此添加到您的答案中。
    • @KeithThompson:完成。
    【解决方案3】:

    如果您查看 7.1/1,您会看到 decl-specifier: 的此语法,这表明 type-specifiertypedef 关键字在语法中处于同一位置,允许您在问题中互换它们(尽管顺便说一句,永远不要写这样的代码,这根本不是惯用的)。

    decl-说明符:

    storage-class-specifier
    
    type-specifier
    
    function-specifier
    
    friend
    
    typedef
    

    【讨论】:

      【解决方案4】:

      我编译使用:

      gcc -c -Wall -Wextra -pedantic -Wconversion -std=gnu99

      在后台,这意味着设置了-Wold-style-declaration

      然后编译器输出如下警告信息:

      warning: 'typedef' is not a beginning of declaration [-Wold-style-declaration]
      

      如果没有设置该参数,编译器可以毫无问题地处理语法

      因此发布的语法符合标准,但可能会让读者感到困惑。

      【讨论】:

        【解决方案5】:
        typedef int INT
        

        使用 typedef 的正确方法

        无论你在哪里使用 INT,它都会被 int 数据类型替换

        这个主要目的是仅将长数据字符串转换为简单值,但在这种情况下,您可以使用普通 int 本身

        您可以仅出于测试目的使用调试,您可以很好地理解

        【讨论】:

          猜你喜欢
          • 2013-08-19
          • 1970-01-01
          • 1970-01-01
          • 2012-12-09
          • 2016-08-13
          • 2020-05-25
          • 2012-11-12
          • 2011-08-01
          • 2018-04-21
          相关资源
          最近更新 更多