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

void foo(A arg){} 

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

Cấu trúc này có phải trả lại cảnh báo/lỗi theo tiêu chuẩn không? Điều gì về các trình biên dịch phổ biến nhất?Sử dụng 'typedef' để đảm bảo an toàn loại hợp lý

Ví dụ: chúng tôi có các biến, đại diện cho kilogram và mét và tất cả đều là loại 'int'. Chúng tôi có một chức năng, xử lý mét. Chúng tôi muốn trình biên dịch bắt lỗi, liên quan đến việc chuyển các kilogram có nghĩa là biến biến thành hàm đó.

Tôi tin rằng Ada sẽ xử lý thuận lợi. Điều gì về hiện đại C?

+1

A 'typedef' đưa ra một mới tên cho một loại hiện có; nó không tạo ra một kiểu mới. Các tên thay thế cũng tham chiếu đến cùng một loại. Vì vậy, tất cả 'A',' B', 'int' và' signed int' có thể được chuyển tới 'foo (A arg)' mà không có sự vi phạm kiểu (và các kiểu khác chuyển thành 'int', chẳng hạn như' enum' các loại, cũng có thể được thông qua mà không gợi ra cảnh báo). –

+0

'void main (void)' nên là 'int main (void)' - và bất kỳ tham chiếu nào đã nói với bạn sử dụng 'void main (void)' được viết bởi một người không biết C rất tốt. –

+0

@KeithThompson, c99 dường như [hỗ trợ] (http://stackoverflow.com/a/9356660/1145760) việc sử dụng này của 'void main (void)'. Sự hiểu lầm là vì tôi đã không gắn thẻ câu hỏi một cách chính xác. – Vorac

Trả lời

7

Không, những gì bạn đang xử lý là một vấn đề kỷ luật được biết đến như tương đương cấu trúc so với tên tương đương. Như Dog đã nói, điều gần nhất bạn có thể làm để đạt được những gì bạn muốn là sử dụng cấu trúc, nhưng điều này có thể là lãng phí bộ nhớ nếu trình biên dịch chọn thêm đệm (trong trường hợp này là không thể). C sử dụng cấu trúc tương đương (có nghĩa là hai loại là cùng một điều) cho các bí danh, nhưng tên tương đương cho các cấu trúc được khai báo khác nhau (hai kiểu struct với cùng một layout không được coi là tương đương).

Một ví dụ của việc sử dụng cấu trúc để làm điều này:

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

Bạn có thể muốn đọc bài viết này: http://www.joelonsoftware.com/articles/Wrong.html mô tả làm thế nào bạn có thể giúp tránh những vấn đề này với quy ước đặt tên

+2

Hậu tố '_t' cho tên loại được đặt trước bởi POSIX. Vì các kiểu sống trong một không gian tên riêng biệt từ các biến, nên không có lý do gì để sử dụng một hậu tố riêng biệt. http://stackoverflow.com/a/231807/139746 –

+1

okay, loại bỏ –

+0

Đây chỉ là một giải pháp nửa chiều vì một ngày một newbie đến và viết 'k.value = m.value;' mà không suy nghĩ sâu hơn về hậu quả . Nếu bạn muốn có sự an toàn thực sự, bạn phải định nghĩa các lớp của riêng bạn (trong trường hợp của bạn có lẽ là gói int như một thành viên dữ liệu) và các toán tử được phép. –

2

Bạn có thể sử dụng cấu trúc với một trường để thực hiện chính xác những gì bạn muốn. "Nhược điểm" duy nhất là bạn sẽ có khả năng lãng phí 1/2/4/8 byte nếu trình tối ưu hóa không tối ưu hóa chúng ...

+3

Kích thước của cấu trúc chỉ là tổng của các kích thước của các biến thành viên của nó cộng với bất kỳ padding (nếu cần thiết). Trong trường hợp chỉ có một biến thành viên, tôi không nghĩ rằng sẽ có bất kỳ chi phí nào về mặt không gian. –

Các vấn đề liên quan