Kích thước bit dài trên Windows 64 bit là bao nhiêu?


137

Cách đây không lâu, có người nói với tôi rằng longkhông phải là 64 bit trên máy 64 bit và tôi nên luôn luôn sử dụng int. Điều này không có ý nghĩa với tôi. Tôi đã thấy các tài liệu (chẳng hạn như tài liệu trên trang web chính thức của Apple) nói rằng đó longthực sự là 64 bit khi biên dịch cho CPU 64 bit. Tôi đã tìm kiếm những gì nó đã có trên Windows 64 bit và tìm thấy

  • Windows: longintduy trì độ dài 32 bit và các loại dữ liệu mới đặc biệt được xác định cho các số nguyên 64 bit.

(từ http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2 )

Tôi nên dùng gì? Tôi có nên định nghĩa một cái gì đó như uw, sw((un) chiều rộng đã ký) là longnếu không có trên Windows, và nếu không thì kiểm tra kích thước bit CPU đích?


Trên Windows có MSVC ++ int và long là 32-bit: msdn.microsoft.com/en-us/l Library / 3b2e7499.aspx . Tuy nhiên, để cho phép các vectơ lưu trữ nhiều hơn 4G vật phẩm, size_t là 64 bit. Vì vậy, người ta cần sử dụng int64_t thay vì int để lặp lại, ví dụ như các vectơ có thể chứa nhiều hơn các mục 4G.
Serge Rogatch


@SergeRogatch họ nên sử dụng size_thoặc một loại trình vòng lặp để lặp lại, không inthoặcint64_t
phuclv

2
@ LưuViênPhúc, với size_tnó trở nên khó khăn gần số âm, vì size_tkhông dấu. Vì vậy, for(size_t i=0; i<v.size()-2; i++)thất bại cho kích thước vectơ 0 và 1. Một ví dụ khác : for(size_t i=v.size()-1; i>=0; i--).
Serge Rogatch

2
Nếu bạn đang làm toán trên con trỏ (nghĩa là với size_tcác giá trị thì kết quả phải được giữ trong một biến ptrdiff_tloại - được thiết kế đủ lớn để giữ kết quả như vậy và là loại được chính xác cho lý do đó!)
SlySven

Câu trả lời:


260

Trong thế giới Unix, có một vài cách sắp xếp có thể cho kích thước của số nguyên và con trỏ cho nền tảng 64 bit. Hai loại được sử dụng rộng rãi là ILP64 (thực ra, chỉ có một vài ví dụ về điều này; Cray là một trong số đó) và LP64 (đối với hầu hết mọi thứ khác). Các từ viết tắt đến từ 'int, long, con trỏ là 64 bit' và 'dài, con trỏ là 64 bit'.

Type           ILP64   LP64   LLP64
char              8      8       8
short            16     16      16
int              64     32      32
long             64     64      32
long long        64     64      64
pointer          64     64      64

Hệ thống ILP64 đã bị bỏ qua vì LP64 (nghĩa là hầu hết tất cả những người tham gia sau này đã sử dụng LP64, dựa trên các khuyến nghị của nhóm Aspen; chỉ các hệ thống có di sản dài 64 bit sử dụng sơ đồ khác). Tất cả các hệ thống Unix 64 bit hiện đại đều sử dụng LP64. MacOS X và Linux đều là các hệ thống 64 bit hiện đại.

Microsoft sử dụng một sơ đồ khác để chuyển sang 64 bit: LLP64 ('dài, con trỏ là 64 bit'). Điều này có ý nghĩa rằng phần mềm 32 bit có thể được biên dịch lại mà không thay đổi. Nó có ưu điểm là khác với những gì mọi người khác làm, và cũng yêu cầu mã phải được sửa đổi để khai thác các dung lượng 64 bit. Luôn luôn có sự sửa đổi cần thiết; nó chỉ là một bộ sửa đổi khác với những bản cần thiết trên nền tảng Unix.

Nếu bạn thiết kế phần mềm của mình xung quanh tên loại số nguyên trung tính nền tảng, có thể sử dụng <inttypes.h>tiêu đề C99 , khi các loại có sẵn trên nền tảng, sẽ cung cấp, ký tên (được liệt kê) và không dấu (không được liệt kê; tiền tố với 'u'):

  • int8_t - Số nguyên 8 bit
  • int16_t - Số nguyên 16 bit
  • int32_t - Số nguyên 32 bit
  • int64_t - Số nguyên 64 bit
  • uintptr_t - số nguyên không dấu đủ lớn để giữ con trỏ
  • intmax_t- kích thước lớn nhất của số nguyên trên nền tảng (có thể lớn hơn int64_t)

Sau đó, bạn có thể mã hóa ứng dụng của mình bằng các loại này khi có vấn đề và rất cẩn thận với các loại hệ thống (có thể khác nhau). Có một intptr_tloại - một loại số nguyên đã ký để giữ con trỏ; bạn nên lập kế hoạch không sử dụng nó, hoặc chỉ sử dụng nó như là kết quả của phép trừ hai uintptr_tgiá trị ( ptrdiff_t).

Nhưng, như câu hỏi chỉ ra (không tin), có các hệ thống khác nhau cho kích thước của các loại dữ liệu số nguyên trên máy 64 bit. Làm quen với nó; thế giới sẽ không thay đổi.


12
Đối với những người sử dụng đã tồn tại đủ lâu, quá trình chuyển đổi 64 bit có một số điểm tương đồng với quá trình chuyển đổi 16 bit sang 32 bit vào giữa những năm 80. Có những máy tính là IL32 và những máy tính khác là L32 (điều chỉnh ký hiệu mới cho vấn đề cũ). Đôi khi 'int' là 16 bit, đôi khi 32 bit.
Jonathan Leffler

4
Đừng quên rằng điều này chỉ áp dụng cho các ngôn ngữ C-ish. Những người khác có thông số kỹ thuật trong đó a) người viết trình biên dịch không được phép chọn kích thước của kiểu dữ liệu willi-nilly hoặc b) biểu diễn vật lý của kiểu dữ liệu không "rò rỉ" hoặc c) số nguyên luôn luôn lớn.
Jörg W Mittag

2
Đúng - nhưng đối với những ngôn ngữ chỉ định hành vi, không có vấn đề gì ở nơi đầu tiên. Ví dụ: Java có 'dài', nhưng kích thước được cố định (64-bit?), Trên tất cả các nền tảng. Vì vậy, không có vấn đề chuyển sang máy 64 bit; kích thước không thay đổi.
Jonathan Leffler

17
@TomFobear: ILP64 trình bày một vấn đề chính - bạn gọi loại 32 bit là gì? Hoặc, nếu bạn gọi loại 32 bit short, bạn gọi loại 16 bit là gì? Và nếu bạn gọi loại 16 bit charcho UTF-16, v.v., bạn gọi loại 8 bit là gì? Vì vậy, việc sử dụng LP64 khiến bạn có 8 bit char, 16 bit short, 32 bit int, 64 bit long, có khả năng mở rộng lên tới 128 bit long longkhi (nếu?) Có liên quan. Sau đó, bạn có nhiều quyền hạn hơn 256 so với tên trong C (vâng, tôi cho rằng bạn có thể có 256-bit intmax_t, và chỉ sau đó bạn mới hết). Có công với LP64.
Jonathan Leffler

2
Có lẽ điều này là hiển nhiên đối với các bạn, nhưng tôi nghĩ rằng đáng chú ý là C # sử dụng các kích thước số nguyên khác nhau từ mọi thứ khác. Gần đây tôi đã vấp phải sự can thiệp với một DLL vì C # sử dụng thời lượng dài 64 bit ( msdn.microsoft.com/en-us/l Library / ms173105.aspx ).
Compholio

57

Không rõ câu hỏi là về trình biên dịch Microsoft C ++ hay API Windows. Tuy nhiên, không có thẻ [c ++] nên tôi cho rằng đó là về API Windows. Một số câu trả lời đã bị thối liên kết vì vậy tôi đang cung cấp một liên kết khác có thể bị thối.


Để biết thông tin về các loại API của Windows như INT, LONGv.v. , có một trang trên MSDN:

Kiểu dữ liệu Windows

Thông tin cũng có sẵn trong các tệp tiêu đề Windows khác nhau như WinDef.h. Tôi đã liệt kê một vài loại có liên quan ở đây:

Loại | S / U | x86 | x64
---------------------------- + ----- + -------- + ------ -
BYTE, BOOLESE | U | 8 bit | 8 bit
---------------------------- + ----- + -------- + ------ -
NGẮN HẠN | S | 16 bit | 16 bit
USHORT, WORD | U | 16 bit | 16 bit
---------------------------- + ----- + -------- + ------ -
INT, DÀI | S | 32 bit | 32 bit
UINT, ULONG, DWORD | U | 32 bit | 32 bit
---------------------------- + ----- + -------- + ------ -
INT_PTR, LONG_PTR, LPARAM | S | 32 bit | 64 bit
UINT_PTR, ULONG_PTR, WPARAM | U | 32 bit | 64 bit
---------------------------- + ----- + -------- + ------ -
DÀI HẠN | S | 64 bit | 64 bit
ULONGLONG, QWORD | U | 64 bit | 64 bit

Cột "S / U" biểu thị đã ký / chưa ký.


4

Bài viết này về MSDN tham khảo một số bí danh loại (có sẵn trên Windows) rõ ràng hơn một chút về chiều rộng của chúng:

http://msdn.microsoft.com/en-us/l Library / aa505945.aspx

Chẳng hạn, mặc dù bạn có thể sử dụng ULONGLONG để tham chiếu giá trị tích phân không dấu 64 bit, bạn cũng có thể sử dụng UINT64. (Điều tương tự cũng xảy ra với ULONG và UINT32.) Có lẽ những điều này sẽ rõ ràng hơn một chút?


1
Có đảm bảo rằng uint32_t và DWORD sẽ được hoán đổi cho nhau không? Không khó để tưởng tượng rằng chúng có thể không [ví dụ: nếu trước đây là 32 bit intvà sau đó là 32 bit long, gcc sẽ cho rằng một con trỏ đến một loại sẽ không thể đặt bí danh cho loại kia mặc dù các đại diện phù hợp của chúng].
supercat


2

Cách dễ nhất để biết về trình biên dịch / nền tảng của bạn:

#include <iostream>

int main() {
  std::cout << sizeof(long)*8 << std::endl;
}

Themultiplication by 8 là lấy bit từ byte.

Khi bạn cần một kích thước cụ thể, thường dễ sử dụng một trong các loại thư viện được xác định trước. Nếu đó là điều không mong muốn, bạn có thể làm những gì thường xảy ra với phần mềm autoconf và để hệ thống cấu hình xác định đúng loại cho kích thước cần thiết.


4
Không phải là vấn đề, nhưng byte 8 bit không thực sự là một phần của thông số C (điều 3.6 và 5.2.4.2.1 của tiêu chuẩn C). Mặc dù bạn sẽ khó có thể tìm thấy một máy có 8 bit, nhưng bạn có thể kiểm tra LONG_BIT để xem kiểu dữ liệu dài của bạn lớn như thế nào.
Andres

Tất nhiên, bạn đúng, nó thực sự phụ thuộc vào kiến ​​trúc ("đơn vị lưu trữ dữ liệu có thể định địa chỉ đủ lớn để chứa bất kỳ thành viên nào trong bộ ký tự cơ bản của môi trường thực thi"), nhưng các kiến ​​trúc được sử dụng phổ biến nhất bằng 8 bit.
Paul de Vrieze

Nhưng OP đã không hỏi về trình biên dịch / nền tảng của anh ấy ; anh ấy đã hỏi cụ thể về Windows 64 bit - có lẽ vì anh ấy không có quyền truy cập thuận tiện vào hệ thống Windows 64 bit để kiểm tra.
Quuxplusone

0

Kích thước tính theo bit của các longnền tảng Windows là 32 bit (4 byte).

Bạn có thể kiểm tra điều này bằng cách sử dụng sizeof(long).


-2

Nếu bạn cần sử dụng các số nguyên có độ dài nhất định, có lẽ bạn nên sử dụng một số tiêu đề độc lập nền tảng để giúp bạn. Boost là một nơi tốt để xem xét.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.