【问题标题】:Why is a typedef not allowed in the inner struct?为什么内部结构中不允许使用 typedef?
【发布时间】:2012-06-14 14:42:20
【问题描述】:

我有一个在现有 typedef 结构中定义 typedef 结构的程序,我想知道为什么会出现编译错误。

这是程序:

typedef struct Outer
{
    typedef struct Inner
    {
        int b;
    }INNER;


    INNER inner;
    int a; 

}OUTER;

int main()
{ 
    OUTER obj;
    obj.a = 10;
    obj.inner.b=8;
    return 0;
}   

编译时出现以下错误::

test.c:3:5: error:expected specifier-qualifier-list before ‘typedef’
test.c: In function ‘main’:
test.c:17:5: error: ‘OUTER’ has no member named ‘a’
test.c:18:5: error: ‘OUTER’ has no member named ‘inner’  

但是,当我将程序更改为

typedef struct Outer
{
    struct Inner
    {
        int b;
    };

    struct Inner inner;
    int a; 

 }OUTER;

 int main()
 {
    OUTER obj;
    obj.a = 10;
    obj.inner.b=8;
    return 0;
 }   

编译成功。

为什么内部结构不允许使用 typedef?

【问题讨论】:

  • 哪个编译器?哪个平台?
  • 因为这是标准?
  • 您应该在第一个示例的第 3 行收到编译错误。如果不是,您使用的是 C++ 编译器,但 C++ 编译器会接受整个程序。
  • @JonathanLeffler gcc 版本 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

标签: c gcc struct typedef


【解决方案1】:

C 不允许在结构成员的声明中使用存储类说明符(typedef,还有staticextern)。这在 C99 中 6.7.2.1p1 中的结构和联合声明的语法中指定。

/* The compiler will issue a diagnostic for this declaration */ 
struct s {    
    static int a;
};

您可以将 6.7.2.1p1 语法与 6.7p1 中声明符不是函数参数或结构/联合成员的声明语法进行比较,并看到在这种情况下允许使用存储类说明符。

【讨论】:

    【解决方案2】:

    struct 定义中包含 typedef 是一种相当奇怪的风格。

    通常应该出现在{} 之间struct 定义的唯一内容是结构成员的声明。

    正如 ouah 所说,struct 定义中的声明不能包含存储类说明符;存储类说明符是typedefexternstaticautoregister(C11 添加了_Thread_local)。这种限制是有道理的,因为结构成员的存储完全由它所属的结构的存储决定。

    typedef是一个特例;它没有指定存储类,但为了语法方便,它被视为存储类说明符

    可以在结构定义中包含其他类型的声明;例如,如您所见,您可以将一个结构声明嵌套在另一个内部。例如,这个程序是有效的(据我所知):

    struct outer {
        struct inner {
            int x;
        };                        // line 4
        struct inner foo;
    };
    
    int main(void) {
        struct outer obj;
        obj.foo.x = 42;
        return 0;
    }
    

    但是 gcc 警告嵌套声明:

    c.c:4:6: warning: declaration does not declare anything [enabled by default]
    

    (在我尝试之前,我会认为这是非法的。)

    UPDATEgcc -pedantic-errors 拒绝此操作并出现致命错误,表明它是非法的。我会尝试用标准来验证这是非法的。

    我认为最好的做法是在一个结构中包含 only 成员声明。如果需要声明另一种类型,请在结构声明之外声明。例如,我会像这样重写问题中的代码:

    typedef struct Inner
    {
        int b;
    } INNER;
    
    typedef struct Outer
    {
        INNER inner;
        int a;
    
    } OUTER;
    
    int main(void)
    {
        OUTER obj;
        obj.a = 10;
        obj.inner.b=8;
        return 0;
    }
    

    (其实我会这样写:

    struct inner {
        int b;
    };
    
    struct outer {
        struct inner inner;
        int a;
    };
    
    int main(void) {
        struct outer obj;
        obj.a = 10;
        obj.inner.b = 8;
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多