2011-12-29 100 views
15

我尝试下面的代码是typedef一个存储类说明符?

#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; 

,我能找到的唯一解释(基于C99规范一些互联网搜索与交叉参考各个部分)为syntactic convenience only to make the grammar simpler

我正在寻找一些理由/解释如何可以类型名称存储类说明符?

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

或我在哪里出错?

回答

14

是的,typedef是您在标准中找到的存储类说明符。部分原因在于语法上的便利,但您可以有意识地将typedef作为更“明显”的存储类别说明符之一。

typedef声明为类型创建别名。

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

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

如果像这样被允许的static没有任何作用,因为没有对象被宣布。被别名的类型只是int

typedef static int sint; 
+1

见:http://stackoverflow.com/questions/2218435/why-typedef-can-not-be-used-with-static – Demi 2011-12-30 01:15:06

4

也许标准应该叫这些东西storage-class-or-typedef-specifier说:

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

那么他们就不会不得不添加的备注语义。

有关语义的评论仅仅是说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(); 
} 

注意的是你使用预处理,以获得“静态类型定义”的效果,这将使bar()静态函数。这可能不是你想要的效果。也许。

1

你不能这样做 - 至少不能在MinGW的GCC中 - 在函数内部或外部。

我会使用预处理器来代替:

#include <stdio.h> 

#define sint static int 

int main(void) 
{ 

    sint i = 10; 

    return 0; 
} 

达到相同的结果。

我想像是因为“static int”不是类似于“volatile int”的类型。

+0

Sh00t,你是对的。我把它与'signed'混淆了。 – 2011-12-29 22:35:40

+3

请不要这样做。它只会让代码更加混乱,sint'不能用作参数类型,并且返回'sint'的函数将具有可能不打算的属性(内部链接)。 – 2011-12-29 23:04:18

-1

typedef在语法上与存储类相同。这不是一个存储类。 typedef与#define相似,但typedef由 编译器解释,而#define由预处理器解释。 typedef可以进行超出预处理器功能的文本替换。

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