Belum lama ini, seseorang mengatakan kepada saya bahwa long
itu bukan 64 bit pada mesin 64 bit dan saya harus selalu menggunakan int
. Ini tidak masuk akal bagi saya. Saya telah melihat dokumen (seperti yang ada di situs resmi Apple) mengatakan bahwa long
memang 64 bit ketika mengkompilasi untuk CPU 64-bit. Saya mencari apa itu di Windows 64-bit dan menemukan
- Windows:
long
danint
panjangnya tetap 32-bit, dan tipe data baru khusus ditentukan untuk integer 64-bit.
(dari http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2 )
Apa yang harus saya gunakan? Haruskah saya mendefinisikan sesuatu seperti uw
, sw
((un) signed width) sebagai long
jika tidak pada Windows, dan sebaliknya melakukan pemeriksaan pada bitsize CPU target?
sizeof(long) == 8
, bahkan di Windows :-)size_t
atau jenis iterator untuk mengulang, bukanint
atauint64_t
size_t
itu menjadi rumit mendekati angka negatif, karenasize_t
unsigned. Jadifor(size_t i=0; i<v.size()-2; i++)
gagal untuk ukuran vektor 0 dan 1. Contoh lain:for(size_t i=v.size()-1; i>=0; i--)
.size_t
nilai maka hasilnya harus disimpan dalam variabelptrdiff_t
tipe - yang dirancang cukup besar untuk menahan hasil seperti itu dan merupakan tipe yang ditandatangani untuk alasan itu!)Jawaban:
Di dunia Unix, ada beberapa kemungkinan pengaturan untuk ukuran integer dan pointer untuk platform 64-bit. Dua yang paling banyak digunakan adalah ILP64 (sebenarnya, hanya sedikit contoh ini; Cray adalah salah satunya) dan LP64 (untuk hampir semua yang lainnya). Akronim berasal dari 'int, long, pointer are 64-bit' dan 'long, pointer are 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
Sistem ILP64 ditinggalkan dan digantikan oleh LP64 (yaitu, hampir semua peserta kemudian menggunakan LP64, berdasarkan rekomendasi dari grup Aspen; hanya sistem dengan warisan panjang operasi 64-bit yang menggunakan skema yang berbeda). Semua sistem Unix 64-bit modern menggunakan LP64. MacOS X dan Linux adalah sistem 64-bit modern.
Microsoft menggunakan skema berbeda untuk beralih ke 64-bit: LLP64 ('panjang, pointer 64-bit'). Ini memiliki arti bahwa perangkat lunak 32-bit dapat dikompilasi ulang tanpa perubahan. Ini memiliki kerugian menjadi berbeda dari apa yang orang lain lakukan, dan juga membutuhkan kode untuk direvisi untuk mengeksploitasi kapasitas 64-bit. Selalu ada revisi yang diperlukan; itu hanyalah serangkaian revisi yang berbeda dari yang dibutuhkan pada platform Unix.
Jika Anda merancang perangkat lunak Anda dengan nama tipe integer platform netral, mungkin menggunakan
<inttypes.h>
header C99 , yang, ketika tipe tersedia di platform, menyediakan, ditandatangani (terdaftar) dan tidak ditandatangani (tidak terdaftar; awalan dengan 'u'):int8_t
- bilangan bulat 8-bitint16_t
- bilangan bulat 16-bitint32_t
- bilangan bulat 32-bitint64_t
- Bilangan bulat 64-bituintptr_t
- bilangan bulat unsigned yang cukup besar untuk menampung pointerintmax_t
- ukuran integer terbesar di platform (mungkin lebih besar dariint64_t
)Anda kemudian dapat mengkodekan aplikasi Anda menggunakan jenis ini di tempat yang penting, dan sangat berhati-hati dengan jenis sistem (yang mungkin berbeda). Ada
intptr_t
tipe - tipe integer bertanda tangan untuk memegang pointer; Anda harus berencana untuk tidak menggunakannya, atau hanya menggunakannya sebagai hasil pengurangan duauintptr_t
nilai (ptrdiff_t
).Tapi, seperti yang ditunjukkan pertanyaan tersebut (tidak percaya), ada sistem yang berbeda untuk ukuran tipe data integer pada mesin 64-bit. Terbiasalah; dunia tidak akan berubah.
sumber
short
, apa yang Anda sebut tipe 16-bit? Dan jika Anda memanggil tipe 16-bitchar
untuk UTF-16 dll, apa yang Anda sebut tipe 8-bit? Jadi, menggunakan LP64 membuat Anda memiliki 8-bitchar
, 16-bitshort
, 32-bitint
, 64-bitlong
, dengan ruang untuk ekspansi ke atas ke 128-bitlong long
ketika (jika?) Itu menjadi relevan. Setelah itu, Anda memiliki lebih banyak kekuatan 256 daripada nama Anda di C (yah, saya kira Anda dapat memiliki 256-bitintmax_t
, dan baru setelah itu Anda kehabisan). Ada manfaatnya untuk LP64.Tidak jelas apakah pertanyaannya tentang kompiler Microsoft C ++ atau Windows API. Namun, tidak ada tag [c ++] jadi saya menganggap ini tentang API Windows. Beberapa jawaban menderita pembusukan tautan jadi saya menyediakan tautan lain yang bisa membusuk.
Untuk informasi tentang jenis Windows API seperti
INT
,LONG
dll. Ada halaman di MSDN:Jenis Data Windows
Informasi ini juga tersedia di berbagai file header Windows seperti
WinDef.h
. Saya telah membuat daftar beberapa jenis yang relevan di sini:Kolom "S / U" menunjukkan tanda tangan / tidak bertanda tangan.
sumber
Artikel di MSDN ini merujuk pada sejumlah alias tipe (tersedia di Windows) yang sedikit lebih eksplisit sehubungan dengan lebarnya:
http://msdn.microsoft.com/en-us/library/aa505945.aspx
Misalnya, meskipun Anda dapat menggunakan ULONGLONG untuk mereferensikan nilai integral 64-bit unsigned, Anda juga dapat menggunakan UINT64. (Hal yang sama berlaku untuk ULONG dan UINT32.) Mungkin ini akan sedikit lebih jelas?
sumber
int
dan yang kedua adalah 32-bitlong
, gcc akan menganggap pointer ke satu jenis tidak akan dapat membuat alias yang lain meskipun representasi mereka cocok].Microsoft juga telah mendefinisikan UINT_PTR dan INT_PTR untuk bilangan bulat yang berukuran sama dengan penunjuk.
Berikut adalah daftar tipe khusus Microsoft - itu bagian dari referensi driver mereka, tapi saya yakin ini juga berlaku untuk pemrograman umum.
sumber
Cara termudah untuk memahaminya untuk kompiler / platform Anda:
#include <iostream> int main() { std::cout << sizeof(long)*8 << std::endl; }
Perkalian dengan 8 adalah mendapatkan bit dari byte.
Saat Anda membutuhkan ukuran tertentu, seringkali paling mudah menggunakan salah satu tipe pustaka yang sudah ditentukan sebelumnya. Jika itu tidak diinginkan, Anda dapat melakukan apa yang sering terjadi dengan perangkat lunak autoconf dan meminta sistem konfigurasi menentukan jenis yang tepat untuk ukuran yang diperlukan.
sumber
Ukuran bit
long
pada platform Windows adalah 32 bit (4 byte).Anda dapat memeriksa ini menggunakan
sizeof(long)
.sumber
Jika Anda perlu menggunakan bilangan bulat dengan panjang tertentu, Anda mungkin harus menggunakan beberapa header platform independen untuk membantu Anda. Boost adalah tempat yang bagus untuk dilihat.
sumber