簡體   English   中英

C:類型定義的名稱空間是什么?

[英]C: what is the name space of a type definition?

typedef名稱在哪個名稱空間中? 考慮以下代碼:

#include <stdio.h>

typedef struct x {   // 'x' in tag name space
   int x;            // 'x' in member name space
   int y;
} x;                 // ??

int main() {
   x foo = { 1, 2 };
   int x = 3;        // 'x' in ordinary identifier name space

   printf("%d %d %d\n", foo.x, foo.y, x);
}

這將使用gcc 4.4.7(和g ++ 4.4.7)打印出“ 1 2 3”,因此類型名稱與標記,成員和普通標識符名稱分開。

此代碼還可以在gcc / g ++ 4.4.7上編譯並運行,產生“ 1、2”:

#include <stdio.h>

typedef struct x {   // 'x' in tag namespace
   int x;            // 'x' in member namespace
   int y;
} x;

int main() {
   x x = { 1, 2 };

   printf("%d %d\n", x.x, x.y);
}

在這種情況下, x標識符如何消除歧義?

編輯 ,我希望澄清。 從上面考慮這兩行:

   x foo = { 1, 2 };
   int x = 3;        // 'x' in ordinary identifier name space

當執行第二行時,標識符x在范圍內,並且在邏輯上應位於“普通標識符”名稱空間中。 此時似乎沒有新的作用域,因為在第1行和第2行之間沒有開括號。因此,第二個x不能隱藏第一個x ,而第二個x是錯誤的。 這個論點有什么缺陷,這對xx案例有何意義? 我的假設是,缺陷在於類型名稱在某種程度上具有不同的非顯而易見的名稱空間,因此是該問題的標題。

它的作用不是由於名稱空間(新的類型名稱和變量標識符在同一普通名稱空間中),而是由於作用域。

6.2.1標識符范圍

2對於標識符指定的每個不同實體,該標識符僅在稱為其作用域的程序文本區域內可見(即可以使用)。 由同一標識符指定的不同實體要么具有不同的范圍,要么處於不同的名稱空間中。 范圍有四種:函數,文件,塊和函數原型。 (函數原型是聲明其參數類型的函數的聲明。)

4每個其他標識符的范圍都由其聲明的位置(在聲明程序或類型說明符中)確定。 如果聲明標識符的聲明符或類型說明符出現在任何參數塊或參數列表之外,則標識符具有文件作用域,該文件作用域終止於轉換單元的末尾。 如果聲明標識符的聲明者或類型說明符出現在功能定義的塊內或參數聲明列表中,則標識符具有塊作用域,該作用域終止於相關塊的末尾。 如果聲明標識符的聲明器或類型說明符出現在函數原型的參數聲明列表中(不是函數定義的一部分),則標識符具有函數原型范圍,該范圍終止於函數聲明符的末尾。 如果標識符在同一名稱空間中指定兩個不同的實體,則范圍可能會重疊。 如果是這樣,一個實體的范圍(內部范圍)將嚴格在另一實體的范圍(外部范圍)之前結束。 在內部范圍內,標識符指定在內部范圍內聲明的實體; 在外部范圍內聲明的實體在內部范圍內隱藏(不可見)。

名為x的變量是內部作用域。 因此,它在外部范圍中隱藏了名為x的實體。 main的作用域內,在聲明xx ,它是一個變量名。

有趣的是xx = { 1, 2 }; x的含義在聲明中更改。 首先,它表示類型名稱,但是一旦聲明器引入標識符, x開始表示變量。


關於您的修改“此參數有何缺陷?” 請注意,范圍可能會重疊(如上一段所述)。 類型別名的定義實際上是在文件范圍內。 main的塊作用域是與外部作用域重疊的新內部作用域。 這就是為什么它可以用來隱藏x的先前含義的原因。 您是否嘗試過在文件范圍內執行此操作:

typedef struct x { /* ... */ } x;
int x = 1; // immediately at file scope

它將是錯誤的形式。 因為現在聲明確實出現在完全相同的范圍內。

暫無
暫無

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

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