簡體   English   中英

為什么內部結構中不允許使用typedef?

[英]Why is a typedef not allowed in the inner struct?

我有一個程序,在現有的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?

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中的結構/聯合成員,並且在這種情況下可以看到存儲類說明符是允許的。

struct定義中包含typedef是相當奇怪的風格。

通常, struct定義的{}之間應該出現的唯一事物是struct成員的聲明。

正如ouah所說, struct定義中的聲明不能包含存儲類說明符; 存儲類說明符是typedefexternstaticautoregister (並且C11添加了_Thread_local )。 這種限制是有道理的,因為結構成員的存儲完全取決於它所屬的結構的存儲。

typedef是一個特例; 它沒有指定存儲類,但為了方便,它被視為存儲類說明符

可以在結構定義中包含其他類型的聲明; 例如,正如您所見,您可以將struct聲明嵌套在另一個中。 例如,這個程序是有效的(據我所知):

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]

(在我嘗試之前,我會認為這是非法的。)

更新gcc -pedantic-errors拒絕此致命錯誤,表明這是非法的。 我會嘗試用標准驗證這是非法的。

我認為最好的做法是在結構中只有成員聲明。 如果需要聲明另一個類型,請在struct聲明之外聲明它。 例如,我會像這樣重寫問題中的代碼:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM