2013-04-05 100 views
7
typedef int A; 
typedef int B; 

void foo(A arg){} 

void main(void){ 
    B wrongvar = 7; 
    foo(wrongvar); 
} 

這個結構是否應該按照標準返回一個警告/錯誤?最受歡迎的編譯器呢?使用'typedef'來確保邏輯類型的安全

例如:我們有變量,代表千克和米,都是'int'類型。我們有一個功能,處理儀表。我們希望編譯器捕捉錯誤,這與將千克含義變量變量傳遞給該函數有關。

我相信Ada處理順利。現代C呢?

+1

一個'typedef'給出了一個新的名稱改爲現有類型;它不會創建一個新的類型。替代名稱也指相同類型。因此,所有'A','B','int'和'signed int'都可以傳遞給'foo(A arg)',而不會違反類型(其他類型可以轉換爲'int',比如'enum'類型,也可以傳遞而不引發警告)。 – 2013-04-28 17:21:06

+0

'void main(void)'應該是'int main(void)' - 任何引用告訴你使用'void main(void)'是由不熟悉C的人編寫的。 – 2016-03-02 21:06:03

+0

@KeithThompson,c99似乎[支持](http://stackoverflow.com/a/9356660/1145760)這種使用'void main(void)'。誤解是因爲我沒有正確地標記問題。 – Vorac 2016-03-07 08:16:12

回答

7

不,您正在處理的是類型問題已知的問題作爲結構對等與名稱對等。正如狗所說,你可以做的最接近的事情就是使用結構,但如果編譯器選擇添加填充(在這種情況下不太可能),這可能會浪費內存。 C對別名使用結構等價(意味着兩種類型是相同的),但是對於不同的聲明結構(具有相同佈局的兩種結構類型不被視爲等同),名稱等價。

使用結構要做到這一點的例子:

typedef struct { 
    double value; 
} meters; 

typedef struct { 
    double value; 
} kilograms; 

int main(){ 
    meters m; 
    kilograms k = {2}; // initialized 
    m.value = 1; 
    k = m; // error, can't assign meters to kilos 
    return 0; 
} 

您不妨看看這篇文章:http://www.joelonsoftware.com/articles/Wrong.html描述瞭如何避免這些問題的命名約定

+2

類型名稱的_t後綴由POSIX保留。由於類型與變量存在於獨立的命名空間中,因此無論如何都沒有理由使用獨特的後綴。 http://stackoverflow.com/a/231807/139746 – 2013-04-28 17:16:26

+1

好吧,消除 – 2013-04-28 17:35:13

+0

這只是一箇中途解決方案,因爲有一天一個新手來寫並寫'k.value = m.value;'沒有更深入地考慮後果。如果你想要有真正的安全性,你必須定義你自己的類(在你的情況可能包裝int作爲數據成員),並允許運營商。 – 2016-03-02 17:10:46

2

你可以使用一個結構與一個字段來做你想要的。唯一的「缺點」是,如果優化器不優化它們,則可能會浪費1/2/4/8字節...

+3

struct的大小隻是其成員變量的大小加上任何填充(如果需要)的總和。如果只有一個成員變量,我認爲在空間方面不會有任何開銷。 – 2013-04-28 16:34:04

相關問題