64 비트 Windows에서 long의 비트 크기는 얼마입니까?


137

얼마 전까지 만해도 누군가 long64 비트 컴퓨터에서 64 비트가 아니라고 말했고 항상 사용해야 int합니다. 이것은 나에게 이해가되지 않았다. 필자는 Apple 공식 사이트의 문서와 같은 문서 long가 64 비트 CPU를 컴파일 할 때 실제로 64 비트 라고 말합니다 . 나는 그것이 64 비트 Windows에서 무엇인지 찾아보고

  • 윈도우 : longint길이가 32 비트를 유지하며, 특별한 새로운 데이터 형식은 64 비트 정수에 대해 정의된다.

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

무엇을 사용해야합니까? Windows에서 아닌 경우 uw, sw((un) 부호가있는 너비)와 같은 것을 정의 long하고 그렇지 않으면 대상 CPU 비트 크기를 확인해야합니까?


: Windows에서 MSVC ++ INT 긴 32 비트입니다 msdn.microsoft.com/en-us/library/3b2e7499.aspx . 그러나 예를 들어 벡터가 4G 이상의 항목을 저장할 수있게하려면 size_t는 64 비트입니다. 따라서 예를 들어 4G보다 많은 항목을 포함 할 수있는 벡터를 반복하려면 int 대신 int64_t를 사용해야합니다.
Serge Rogatch 2016 년


그들이 사용한다 @SergeRogatch size_t또는 반복 반복자 타입이 아닌 intint64_t
phuclv

2
@ LưuVĩnhPhúc 은 부호 size_t가 없으므로 음수 근처에서 까다로워집니다 size_t. 그래서 for(size_t i=0; i<v.size()-2; i++)벡터의 크기를 0과 1의 또 다른 예를 들어 실패합니다 for(size_t i=v.size()-1; i>=0; i--).
Serge Rogatch

2
포인터에 대해 수학을 수행하는 경우 (예 : size_t값을 사용하여 결과는 ptrdiff_t유형 의 변수로 유지되어야합니다.이 결과는 그러한 결과를 보유 할 수있을만큼 충분히 크도록 설계되었으며 정확하게 그런 이유로 서명 된 유형입니다!)
SlySven

답변:


261

유닉스 세계에서, 64 비트 플랫폼을위한 정수와 포인터의 크기에 대한 몇 가지 가능한 배열이있었습니다. 가장 널리 사용되는 두 가지는 ILP64 (실제로이 예는 극소수에 불과합니다. 약어는 'int, long, 포인터는 64 비트'및 'long, 포인터는 64 비트'에서 나옵니다.

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

ILP64 시스템은 LP64 에 찬성하여 포기되었습니다. 즉, 거의 모든 이후 참가자는 아스펜 그룹의 권장 사항에 따라 LP64를 사용했습니다. 모든 최신 64 비트 유닉스 시스템은 LP64를 사용합니다. MacOS X와 ​​Linux는 모두 최신 64 비트 시스템입니다.

Microsoft는 64 비트로 전환하기 위해 LLP64 ( '길이가 길고 포인터가 64 비트')라는 다른 체계를 사용합니다. 이는 32 비트 소프트웨어를 변경하지 않고 다시 컴파일 할 수 있다는 의미가 있습니다. 그것은 다른 사람들과 다른 단점이 있으며 64 비트 용량을 이용하기 위해 코드를 수정해야합니다. 항상 수정이 필요했습니다. 그것은 유닉스 플랫폼에서 필요한 것과는 다른 개정 세트였습니다.

플랫폼 중립 정수 유형 이름을 중심으로 소프트웨어를 설계하는 경우 C99 <inttypes.h>헤더를 사용 하여 플랫폼에서 유형을 사용할 수있는 경우 부호있는 (목록에있는) 및 부호없는 (나열되지 않은 접두사 : 'u')를 제공합니다.

  • int8_t -8 비트 정수
  • int16_t -16 비트 정수
  • int32_t -32 비트 정수
  • int64_t -64 비트 정수
  • uintptr_t -포인터를 담을 수있을 정도로 큰 부호없는 정수
  • intmax_t-플랫폼에서 가장 큰 정수 크기 (보다 클 수 있음 int64_t)

그런 다음, 이러한 유형을 중요한 곳에 사용하고 시스템 유형 (상이 할 수 있음)에 매우주의하여 응용 프로그램을 코딩 할 수 있습니다. 이 intptr_t유형 - 포인터를 유지하는 부호있는 정수 유형으로, 사용하지 않거나 두 uintptr_t값을 뺀 결과로만 사용하도록 계획해야 합니다 ( ptrdiff_t).

그러나 문제가 불신으로 지적한 것처럼 64 비트 시스템에는 정수 데이터 유형의 크기에 따라 다른 시스템이 있습니다. 그것에 익숙해; 세상은 변하지 않을 것입니다.


12
오래 전부터 사용했던 사람들에게 64 비트 전환은 80 년대 중반의 16 비트에서 32 비트로의 전환과 유사합니다. IL32 인 컴퓨터와 L32 인 다른 컴퓨터가있었습니다 (이전 문제에 새로운 표기법을 적용). 때때로 'int'는 16 비트, 때로는 32 비트입니다.
Jonathan Leffler

4
이것은 C 언어로만 적용된다는 것을 잊지 마십시오. 다른 사람들은 a) 컴파일러 작성자가 데이터 유형의 크기를 임의로 선택할 수 없거나 b) 데이터 유형의 물리적 표현이 "누수"하지 않거나 c) 정수가 항상 무한대로 큰 사양을 가지고 있습니다.
Jörg W Mittag

2
사실이지만 동작을 지정하는 언어의 경우 처음에는 문제가 없습니다. 예를 들어, Java에는 '길이'가 있지만 모든 플랫폼에서 크기는 고정되어 있습니다 (64 비트?). 따라서 64 비트 시스템으로 이식하는 데 문제가 없습니다. 크기는 변하지 않습니다.
Jonathan Leffler

17
@TomFobear : ILP64는 한 가지 중요한 문제를 제시합니다. 32 비트 유형은 무엇입니까? 또는 32 비트 유형 short을 호출하면 16 비트 유형을 무엇이라고합니까? charUTF-16 등 의 16 비트 유형 을 호출하면 8 비트 유형은 무엇입니까? 따라서 LP64를 사용하면 8 비트 char, 16 비트 short, 32 비트 int, 64 비트 long를 사용할 수 있으며 long long관련성이있는 경우 128 비트 이상으로 확장 할 수있는 공간 이 생깁니다. 그 후에 C에있는 이름보다 256의 힘을 더 많이 얻습니다 (256 비트를 가질 수 있다고 생각합니다 intmax_t. LP64에는 장점이 있습니다.
Jonathan Leffler

2
어쩌면 이것은 여러분에게 분명하지만 C #은 다른 모든 정수 크기를 사용한다는 점에 주목할 가치가 있다고 생각합니다. C #에서 64 비트 길이 ( msdn.microsoft.com/en-us/library/ms173105.aspx )를 사용하기 때문에 최근 DLL과의 인터페이스가 트립되었습니다 .
Compholio

57

Microsoft C ++ 컴파일러 또는 Windows API에 대한 질문인지 확실하지 않습니다. 그러나 [c ++] 태그가 없으므로 Windows API에 관한 것으로 가정합니다. 답변 중 일부가 링크 썩음으로 어려움을 겪었으므로 썩을 수있는 또 다른 링크를 제공하고 있습니다.


같은 윈도우 API 유형에 대한 자세한 내용은 INT, LONG등 MSDN에 페이지가있다 :

Windows 데이터 유형

이 정보는와 같은 다양한 Windows 헤더 파일에서도 사용할 수 있습니다 WinDef.h. 여기에 몇 가지 관련 유형이 나열되어 있습니다.

타입 | S / U | x86 | x64
---------------------------- + ----- + -------- + ------ -
부산, 바이트 | U | 8 비트 | 8 비트
---------------------------- + ----- + -------- + ------ -
짧은 | S | 16 비트 | 16 비트
우호, 단어 | U | 16 비트 | 16 비트
---------------------------- + ----- + -------- + ------ -
INT, LONG | S | 32 비트 | 32 비트
UINT, ULONG, DWORD | U | 32 비트 | 32 비트
---------------------------- + ----- + -------- + ------ -
INT_PTR, LONG_PTR, LPARAM | S | 32 비트 | 64 비트
UINT_PTR, ULONG_PTR, WPARAM | U | 32 비트 | 64 비트
---------------------------- + ----- + -------- + ------ -
긴 | S | 64 비트 | 64 비트
ULONGLONG, QWORD | U | 64 비트 | 64 비트

"S / U"열은 부호있는 / 부호없는 것을 나타냅니다.


4

MSDN 의이 기사는 너비와 관련하여 좀 더 명백한 여러 유형 별칭 (Windows에서 사용 가능)을 참조합니다.

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

예를 들어 ULONGLONG을 사용하여 부호없는 64 비트 정수 값을 참조 할 수 있지만 UINT64를 사용할 수도 있습니다. (ULONG과 UINT32도 마찬가지입니다.) 아마도 이것들은 조금 더 명확할까요?


1
uint32_t와 DWORD가 호환 가능하다는 보장이 있습니까? 그것들이 그렇지 않을 것이라고 상상하기 어렵지 않다 [예를 들어 전자가 32 비트 int이고 후자가 32 비트 인 경우 long, gcc는 일치하는 표현에도 불구하고 한 타입에 대한 포인터가 다른 타입의 앨리어싱을 할 수 없을 것이라고 가정한다].
supercat

4

또한 Microsoft는 포인터와 동일한 크기의 정수에 대해 UINT_PTR 및 INT_PTR을 정의했습니다.

다음은 Microsoft 특정 유형목록입니다 -드라이버 참조의 일부이지만 일반 프로그래밍에도 유효하다고 생각합니다.


2

컴파일러 / 플랫폼에 대해 가장 쉽게 알 수있는 방법은 다음과 같습니다.

#include <iostream>

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

8을 곱하면 바이트에서 비트를 얻는 것입니다.

특정 크기가 필요한 경우 사전 정의 된 유형의 라이브러리 중 하나를 사용하는 것이 가장 쉬운 경우가 많습니다. 이것이 바람직하지 않은 경우 autoconf 소프트웨어에서 자주 발생하는 작업을 수행하고 구성 시스템이 필요한 크기에 적합한 유형을 결정하도록 할 수 있습니다.


4
중요한 것은 아니지만 8 비트 바이트는 실제로 C 스펙의 일부가 아닙니다 (C 표준 3.6 및 5.2.4.2.1 절). 8 비트가 아닌 머신을 찾기가 어려울지라도 LONG_BIT를 확인하여 긴 데이터 유형이 얼마나 큰지 확인할 수 있습니다.
Andres

물론, 당신은 맞습니다, 그것은 실제로 아키텍처에 달려 있습니다 ( "실행 환경의 기본 문자 집합의 멤버를 보유 할 수있을 정도로 큰 주소 지정 가능한 데이터 스토리지 단위"). 그러나 가장 일반적으로 사용되는 아키텍처는 8 비트입니다.
Paul de Vrieze

그러나 영업 이익에 대해 질문하지 않았다 자신의 컴파일러 / 플랫폼; 그는 특히 64 비트 Windows에 대한 질문 - 그는 아마도 때문에 하지 않습니다 에 대한 테스트에 대한 64 비트 Windows 시스템에 편리하게 액세스 할 수 있습니다.
Quuxplusone

0

longWindows 플랫폼 에서 비트 크기 는 32 비트 (4 바이트)입니다.

를 사용하여 확인할 수 있습니다 sizeof(long).


-2

특정 길이의 정수를 사용해야하는 경우 플랫폼 독립 헤더를 사용해야합니다. 부스트는보기 좋은 곳입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.