2011-09-30 74 views
14

Tôi đã tải xuống MinGW-64, vì vậy bây giờ tôi có thể biên dịch chương trình 64 bit cho Windows 7, sử dụng g ++ 4.7.0 (thử nghiệm). Nhưng dòng sau:sizeof (dài) trong 64-bit C++

cout << sizeof(long) << " " << sizeof(void*) << endl ; 

in 4 8, không 8 8. Các tài liệu cho g ++ 4.6.0 nói:

các bộ môi trường 64-bit int đến 32 bit và dài và con trỏ đến 64 bit

Có ai biết tại sao không phải là sizeof(long) 8?

Đã chỉnh sửa để thêm: Nguồn gây nhầm lẫn của tôi là g ++ 4.7.0 cho Windows 64 bit không phải là một phần chính thức của Bộ sưu tập GNU Compiler. Và đây là phiên bản 64 bit đầu tiên với long 32 bit, vì vậy tài liệu đơn giản không áp dụng cho nó. Thật vậy, nếu bạn đi đến relevant web page, mục đầy đủ cho IA-32/x86-64 gồm này:

...

+2

Có vẻ như ai đó vừa giảm xuống một nửa số câu trả lời mà không để lại bất kỳ bình luận nào ... – Mysticial

+0

@ Tâm lý: Và câu hỏi của tôi nữa! – TonyK

+0

Nếu bạn cần số nguyên rộng 64 bit, hãy sử dụng int64_t/uint64_t hoặc xác định số của riêng bạn. Bằng cách đó, mã của bạn sẽ được di chuyển và sẽ không dựa vào chi tiết nền tảng cho các kích thước int/long/short. – David

Trả lời

15

Vì không cần thiết. Tiêu chuẩn C++ chỉ yêu cầu nó là (nếu bộ nhớ phục vụ) ít nhất 32 bit, và ít nhất là lớn như int.

MSVC (và ABI sử dụng bởi Windows) định nghĩa long là 32 bit rộng, và MinGW sau phù hợp vì tốt, trình biên dịch là hữu ích hơn nhiều khi nó đồng ý với các hệ điều hành máy chủ

+1

Tôi không nói về tiêu chuẩn C++, tôi đang nói về tài liệu của GNU Compiler Collection. – TonyK

+4

Tôi biết. Vì vậy, đọc câu đầu tiên trong câu trả lời của tôi. Và điều cuối cùng. Tài liệu bạn chỉ tìm thấy (tôi giả định) mô tả ABI cho Linux đang chạy trên x64.Nó không nói gì về các CPU khác (ARM, MIPS, Alpha, SPARC hay bất kỳ thứ gì khác), và nó không nói gì về các cổng cho các hệ điều hành khác nhau. – jalf

11

Trên OS cửa sổ microsoft bạn có LLP64 nên kích thước dài là 32 bit. (Xem bảng dưới đây)

Trích từ wikipedia:

Trong chương trình 32-bit, con trỏ và các loại dữ liệu như số nguyên thường có cùng độ dài; điều này không nhất thiết phải đúng trên các máy 64 bit. Việc trộn các kiểu dữ liệu trong các ngôn ngữ lập trình như C và các hậu duệ của nó như C++ và Objective-C có thể hoạt động trên các triển khai 32 bit nhưng không hoạt động trên các triển khai 64 bit. Trong nhiều môi trường lập trình cho các ngôn ngữ C và C có nguồn gốc trên các máy 64 bit, các biến "int" vẫn rộng 32 bit, nhưng các số nguyên và con trỏ dài rộng 64 bit. Chúng được mô tả là có mô hình dữ liệu LP64. Một lựa chọn khác là mô hình dữ liệu ILP64, trong đó tất cả ba kiểu dữ liệu đều rộng 64 bit và thậm chí là SILP64 trong đó các số nguyên "ngắn" cũng rộng 64 bit. Tuy nhiên, trong hầu hết các trường hợp, các sửa đổi được yêu cầu tương đối nhỏ và đơn giản, và nhiều chương trình được viết tốt có thể được biên dịch lại một cách đơn giản cho môi trường mới mà không có thay đổi. Một lựa chọn khác là mô hình LLP64, duy trì khả năng tương thích với mã 32 bit bằng cách để cả hai int và dài 32 bit. "LL" dùng để chỉ loại "số nguyên dài", ít nhất 64 bit trên tất cả các nền tảng, kể cả môi trường 32 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 
+1

Có lẽ một chút giải thích về những gì bảng * có nghĩa là *? ;) – jalf

+1

Làm thế nào về một liên kết tham khảo? –

+0

Ở đây các mô hình khác nhau được giải thích: http://en.wikipedia.org/wiki/64-bit –

0

Đó là hệ điều hành cụ thể. Windows vẫn có kích thước dài bằng 32 bit

0

Hầu hết các ứng dụng Windows được viết với kỳ vọng cho tất cả các ý định và mục đích int = long = 32 bit. Tôi đoán MinGW chỉ là đảm bảo nó vẫn là trường hợp và không có bất ngờ.

2

MinGW được thiết kế để xây dựng ứng dụng WIN32 và các tiêu đề/thư viện WIN32 giả sử loại dài (hoặc LONG) rộng 32 bit ngay cả trên Windows 64 bit. Microsoft đã quyết định rằng nếu không nhiều mã nguồn Windows hiện có sẽ được thay đổi. Ví dụ, cấu trúc sau đây sử dụng loại LONG.

typedef struct tagBITMAPINFOHEADER { 
... 
    LONG biWidth; 
    LONG biHeight; 
... 
} BITMAPINFOHEADER 

;

+0

'LONG' chỉ là một macro. Nó có thể dễ dàng thay đổi thành 'int32_t', vì vậy đây không phải là lý do hợp lệ. – rustyx

0

MinGW được thiết kế để xây dựng các ứng dụng Windows và nền tảng Microsoft ABI specifies rằng intlong có cùng kích thước 32 bit. Nếu MinGW xác định long khác với MSVC, hầu hết các ứng dụng Windows hiện có sử dụng long sẽ bị ngắt khi được biên dịch bằng cách sử dụng MinGW.

Có nói rằng, Cygwin x86_64 thực hiện theo quy ước LP64 trên Windows, giống như trên Linux (source).

Vì vậy, bạn có thể sử dụng để xây dựng một ứng dụng Windows mà kích thước của long là 8 byte :)

Kiểm tra trường hợp:

#include <stdio.h> 
#include <windows.h> 

int CALLBACK WinMain(HINSTANCE a, HINSTANCE b, LPSTR c, int d) 
{ 
    char buf[100]; 
    snprintf(buf, sizeof(buf), 
    "sizeof(int)=%d, sizeof(long)=%d, sizeof(long long)=%d\n", 
    sizeof(int), sizeof(long), sizeof(long long)); 
    MessageBox(NULL, buf, "Cygwin Test", MB_OK); 
    return 0; 
} 

Compile với: C:\cygwin64\bin\gcc.exe -mwindows -m64 cygwin-test.c -o cygwin-test

Output:

Windows 64-bit LP64 using Cygwin