【问题标题】:Is typedef a storage-class-specifier?typedef 是存储类说明符吗?
【发布时间】:2012-01-30 05:56:51
【问题描述】:

我尝试了以下代码

#include <stdio.h>

int main(void)
{
    typedef static int sint;
    sint i = 10;

    return 0;
}

并遇到以下错误:

error: multiple storage classes in declaration specifiers

当我参考 C99 规范时,我知道typedefstorage class

6.7.1 Storage-class specifiers

Syntax

storage-class-specifier:
    typedef
    extern
    static
    auto
    register

Constraints: At most, one storage-class specifier may be 
             given in the declaration specifiers in a declaration

Semantics: The typedef specifier is called a ‘‘storage-class specifier’’ 
           for syntactic convenience only; 

我能找到的唯一解释是syntactic convenience only to make the grammar simpler

我正在寻找一些关于类型名称如何具有存储类说明符的理由/解释?

typedef static int sint; 这样的代码难道没有意义吗?

或者我哪里错了?!

【问题讨论】:

    标签: c typedef


    【解决方案1】:

    是的,typedef 是您在标准中找到的存储类说明符。在某种程度上,这是为了语法上的便利,但故意让您可以使用typedef 更“明显”的存储类说明符之一。

    typedef 声明为类型创建别名。

    在声明 static int x; 中,x 的类型是 intstatic 与类型无关。

    (考虑如果你取x的地址,&amp;x的类型为int*int *y = &amp;x;static int *z = &amp;x一样是合法的,但后者static影响z的存储类并且独立于x的存储类。)

    如果允许这样的事情,static 将不起作用,因为没有对象被声明。被别名的类型只是int

    typedef static int sint;
    
    【解决方案2】:

    也许标准应该将这些东西称为storage-class-or-typedef-specifier并说:

    约束:在声明中的声明说明符中最多可以给出一个 storage-classor-typedef-specifier

    那么他们就不必添加有关语义的注释。

    关于语义的评论只是说typedef 实际上并没有控制用于该类型的存储的任何内容(因此它在语义上不是“存储说明符”),但它在句法上的处理方式类似于其他storage-class-specifier,因此不能与它们一起使用。

    因此,typedef 无法确定特定类型实例的存储位置 - 这取决于实例的实际声明(隐式或显式)。

    我敢肯定,即使您要查找的内容是允许的,这也是一种不好的做法。考虑:

    // in someheader.h
    typedef static int sint;
    
    
    // now in foo.c
    #include "someheader.h"
    
    int foo(void)
    {
        sint i = 10;   // unless you're intimately knowledgeable about how 
                       //    `sint` is typedef'ed, this looks exactly like
                       //    an automatic
    
    
        // do some stuff that modifies `i`...
    
        return i;
    }
    
    sint bar(void)    // what does this mean?  is `bar()` static?
    {
        return foo();
    }
    

    请注意,您是否使用预处理器来获得“静态 typedef”效果,这会使 bar() 成为静态函数。这可能不是您想要的效果。也许吧。

    【讨论】:

      【解决方案3】:

      你不能这样做——至少不能使用 MinGW 的 GCC——在函数内部或外部。

      我会改用预处理器:

      #include <stdio.h>
      
      #define sint static int
      
      int main(void)
      {
      
          sint i = 10;
      
          return 0;
      }
      

      达到同样的效果。

      我想这是因为“static int”与“volatile int”不同。

      【讨论】:

      • 请不要这样做。它只会使代码比它必须的更混乱,sint 将不能用作参数类型,并且返回 sint 的函数将具有可能不是预期的属性(内部链接)。
      【解决方案4】:

      typedef 在语法上与存储类相同。它不是一个存储类。 typedef 在效果上类似于 #define,但 typedef 由 编译器,而#define 是由预处理器。 typedef 可以进行超出 预处理器。

      使用 typedef 的两个目的 1. 便携性 2. 更好的文档

      【讨论】:

        猜你喜欢
        • 2011-04-28
        • 1970-01-01
        • 1970-01-01
        • 2012-05-17
        • 1970-01-01
        • 1970-01-01
        • 2014-02-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多