2011-12-24 28 views
39

Kể từ C# hỗ trợ Int8, Int16, Int32Int64, tại sao các nhà thiết kế của ngôn ngữ chọn để xác định int như một bí danh cho Int32 thay vì cho phép nó thay đổi tùy theo những gì các kiến ​​trúc bản địa coi là một word?Trong C#, tại sao "int" là một bí danh cho System.Int32?

Tôi chưa có bất kỳ nhu cầu cụ thể nào đối với int để hoạt động khác với cách thực hiện, tôi chỉ yêu cầu ra khỏi sở thích bách khoa toàn bộ. Tôi có thể nghĩ rằng kiến ​​trúc RISC 64 bit có thể tồn tại một cách có hiệu quả, chỉ hỗ trợ hiệu quả nhất với số lượng 64 bit và trong đó các thao tác với số lượng 32-bit sẽ yêu cầu các hoạt động bổ sung. Một kiến ​​trúc như vậy sẽ gây bất lợi cho một thế giới trong đó các chương trình khăng khăng sử dụng các số nguyên 32 bit, đó là một cách khác để nói rằng C#, trở thành ngôn ngữ của tương lai và tất cả, về cơ bản ngăn cản các nhà thiết kế phần cứng không bao giờ đến với một kiến ​​trúc trong tương lai.

StackOverflow không khuyến khích suy đoán câu trả lời, vì vậy vui lòng chỉ trả lời nếu thông tin của bạn đến từ nguồn đáng tin cậy. Tôi đã nhận thấy rằng một số thành viên của SO là người trong Microsoft, vì vậy tôi đã hy vọng rằng họ có thể khai sáng cho chúng tôi về chủ đề này.

Lưu ý 1: Tôi đã làm trong thực tế đọc tất cả câu trả lời và tất cả các ý kiến ​​của SO: Is it safe to assume an int will always be 32 bits in C#? nhưng không tìm thấy bất kỳ gợi ý để các tại sao rằng Tôi yêu cầu trong câu hỏi này.

Note 2: khả năng tồn tại của câu hỏi này trên SO là (inconclusively) thảo luận ở đây: Meta: Can I ask a “why did they do it this way” type of question?

+4

Nếu bạn muốn có một "loại máy có kích thước từ", bạn đang tìm kiếm 'System.IntPtr'. –

+0

Có, nhưng chúng tôi có xu hướng làm số học với 'int', không phải với 'IntPtr' s. –

+7

Tại sao các downvotes ?? – gdoron

Trả lời

33

Tôi tin rằng nguyên nhân chủ yếu của họ là tính di động của các chương trình mục tiêu CLR. Nếu họ cho phép loại hình cơ bản như int phụ thuộc vào nền tảng, việc tạo các chương trình di động cho CLR sẽ trở nên khó khăn hơn nhiều. Sự gia tăng của các loại tích hợp typedef trong mã C/C++ trung lập nền tảng để sử dụng được xây dựng trong int là một gợi ý gián tiếp về lý do tại sao các nhà thiết kế của CLR quyết định tạo sẵn các loại nền tảng độc lập. Sự khác biệt như vậy là một chất ức chế lớn cho mục tiêu "viết một lần, chạy bất cứ đâu" của các hệ thống thực thi dựa trên các máy ảo.

Sửa Thường xuyên hơn không, kích thước của một int lượt vào mã của bạn ngầm thông qua các hoạt động chút, chứ không phải thông qua arithmetics (sau khi tất cả, điều gì có thể đi sai với i++, phải không?) Tuy nhiên, lỗi này thường tinh tế hơn. Hãy xem xét ví dụ bên dưới:

const int MaxItem = 20; 
var item = new MyItem[MaxItem]; 
for (int mask = 1 ; mask != (1<<MaxItem) ; mask++) { 
    var combination = new HashSet<MyItem>(); 
    for (int i = 0 ; i != MaxItem ; i++) { 
     if ((mask & (1<<i)) != 0) { 
      combination.Add(item[i]); 
     } 
    } 
    ProcessCombination(combination); 
} 

Mã này tính toán và xử lý tất cả các kết hợp của 20 mục. Như bạn có thể nói, mã không thành công trên một hệ thống với 16-bit int, nhưng hoạt động tốt với ints 32 hoặc 64 bit.

Mã không an toàn sẽ cung cấp một nguồn nhức đầu khác: khi số int được cố định ở một số kích thước (ví dụ 32) mã phân bổ gấp 4 lần số byte là số lượng int cần phải sắp xếp, mặc dù về mặt kỹ thuật là không chính xác để sử dụng 4 thay cho sizeof(int). Hơn nữa, mã không chính xác về mặt kỹ thuật này sẽ vẫn hoạt động!

Cuối cùng, những điều nhỏ nhặt như vậy chơi rất nhiều vào nhận thức về nền tảng là "tốt" hoặc "xấu". Người dùng.NET chương trình không quan tâm rằng một chương trình bị treo vì lập trình viên của nó đã thực hiện một sai lầm không di động, hoặc CLR là lỗi. Điều này tương tự như cách Windows đầu tiên được nhận thức rộng rãi là không ổn định do chất lượng trình điều khiển kém. Đối với hầu hết người dùng, sự cố chỉ là một sự cố chương trình .NET khác, không phải vấn đề của người lập trình. Vì vậy là tốt cho nhận thức của "hệ sinh thái .NET" để làm cho tiêu chuẩn như là tha thứ nhất có thể.

+0

Vâng, tôi chắc chắn rằng cuối cùng nó bằng cách nào đó nắm xuống tính di động, nhưng tôi không thấy chính xác như thế nào. Bạn thấy đấy, chúng tôi rất hiếm khi thực hiện các phép tính số học mà kết quả thực sự phụ thuộc vào độ dài bit cụ thể của các toán hạng của chúng tôi, và đối với những trường hợp hiếm hoi đó. Int32, Int64 và phiên bản chưa ký của chúng. –

+0

Hơn nữa, trình biên dịch/JIT có thể dễ dàng cung cấp cho chúng tôi các phiên bản biên dịch khác nhau của chương trình cho kích thước từ máy 4 byte và kích thước từ máy 8 byte để chúng tôi có thể kiểm tra nó trong cả hai kịch bản trên một máy phát triển đơn lẻ. –

+0

@MikeNakis Điều đó có vẻ là một giả định tốt ngoại trừ việc nó bị hỏng nếu bạn mã cho 64 bit, và sau đó cố gắng chạy trên 32 bit, các giả định về số nguyên tối thiểu và tối đa có thể làm cho mã của bạn bị hỏng. Nó cũng có thể phá vỡ mã tùy chỉnh được viết để phân tích cú pháp/định dạng số nguyên dưới dạng chuỗi. Hãy nhớ rằng ý tưởng của những môi trường này được đảm bảo nhiều tính di động hơn bất cứ thứ gì khác. –

6

Nhiều lập trình viên có xu hướng viết mã cho nền tảng mà họ sử dụng. Điều này bao gồm các giả định về kích thước của một loại. Có rất nhiều chương trình C xung quanh sẽ thất bại nếu kích thước của một int sẽ được thay đổi thành 16 hoặc 64 bit bởi vì chúng được viết dưới giả định rằng một int là 32 bit. Sự lựa chọn cho C# tránh được vấn đề đó bằng cách định nghĩa nó như thế. Nếu bạn định nghĩa int là biến phụ thuộc vào nền tảng bạn quay trở lại vào cùng một vấn đề đó. Mặc dù bạn có thể cho rằng đó là lỗi của các lập trình viên khi đưa ra giả định sai khiến nó trở nên mạnh mẽ hơn một chút (IMO). Và đối với các nền tảng máy tính để bàn, int 32 bit có lẽ là sự xuất hiện phổ biến nhất. Bên cạnh đó nó làm cho việc chuyển mã C gốc sang C# dễ dàng hơn một chút.

Chỉnh sửa: Tôi nghĩ bạn viết mã tạo nên các giả định (ngụ ý) về trình kích hoạt của loại thường xuyên hơn bạn nghĩ. Về cơ bản bất cứ thứ gì liên quan đến serialization (như .NET remoting, WCF, serializing dữ liệu vào đĩa, vv) sẽ giúp bạn gặp rắc rối nếu bạn cho phép biến kích cỡ cho int trừ khi lập trình viên quản lý nó bằng cách sử dụng loại có kích thước cụ thể như int32. Và sau đó bạn kết thúc với "chúng tôi sẽ luôn luôn sử dụng int32 chỉ trong trường hợp" và bạn đã đạt được không có gì.

+0

Vui lòng xem nhận xét đầu tiên của tôi về câu trả lời của @ dasblinkenlight. –

+0

@MikeNakis: Tôi đã cập nhật câu trả lời của mình – ChrisWue

+0

Ngay cả việc tuần tự hóa/từ một phương tiện nhị phân có thể được quan tâm bằng các thuộc tính, vì vậy ví dụ tôi có thể khai báo 'i' thành một native int, và tôi có thể gắn một thuộc tính vào nó nói rằng nó có nghĩa là được tuần tự hóa như một số lượng nhỏ 32-bit cuối. Nhưng trong mọi trường hợp, tôi thấy công đức trong phần cuối của những gì bạn nói, rằng "sau đó bạn kết thúc với" chúng tôi sẽ sử dụng int32 luôn luôn anyway chỉ trong trường hợp 'và bạn đã đạt được không có gì ". Vì vậy, điểm mấu chốt là, tôi tự hỏi liệu Microsoft có thực hiện bất kỳ loại nghiên cứu nào và xác định rằng điều này chắc chắn sẽ là trường hợp cuối cùng. –