다른 유형에 대한 포인터의 크기가 다른 플랫폼이 있습니까?
C 표준은 다른 유형에 대한 포인터가 다른 크기를 갖도록 sizeof(char*) != sizeof(int*)
허용합니다 ( 예 : 허용됨). 그러나 포인터가 a void*
로 변환 된 다음 다시 원래 유형으로 변환되면 원래 값과 동일한 것으로 비교해야합니다. 따라서 논리적으로 sizeof(void*) >= sizeof(T*)
모든 유형 T
에 대해 맞습니까?
오늘날 사용되는 가장 일반적인 플랫폼 (x86, PPC, ARM 및 64 비트 변형 등)에서 모든 포인터의 크기는 지정 대상 유형에 관계없이 기본 레지스터 크기 (4 또는 8 바이트)와 같습니다. 다른 유형에 대한 포인터의 크기가 다를 수있는 난해하거나 임베디드 플랫폼이 있습니까? 함수 포인터가 비정상적인 크기를 갖는 플랫폼이 있는지도 알고 싶지만 데이터 포인터 에 대해 구체적으로 묻고 있습니다 .
나는 C ++의 포인터-멤버와 포인터-멤버-함수에 대해 확실히 묻지 않는다 . 그것들은 일반적인 플랫폼에서 비정상적인 크기를 취하고, 포인터에 대한 클래스 (비다 형성, 단일 상속, 다중 상속, 가상 상속 또는 불완전 유형)의 속성에 따라 하나의 플랫폼 내에서도 달라질 수 있습니다.
Prime 50 시리즈는 최소한 PL / I에 대해 널 포인터에 대해 세그먼트 07777, 오프셋 0을 사용했습니다. 이후 모델은 C의 널 포인터에 대해 세그먼트 0, 오프셋 0을 사용했으며, TCNP (Test C Null Pointer)와 같은 새로운 명령이 필요했습니다. 이전의 단어 주소가 지정된 Prime 시스템은 단어 포인터 (int *)보다 더 큰 바이트 포인터 (char *)를 요구하는 것으로 악명이 높습니다.
Data General의 Eclipse MV 시리즈에는 아키텍처 적으로 지원되는 세 가지 포인터 형식 (워드, 바이트 및 비트 포인터)이 있으며,이 중 두 가지는 C 컴파일러에서 사용됩니다. char * 및 void *에 대한 바이트 포인터와 그 밖의 모든 것에 대한 워드 포인터입니다. 16 비트 Nova 라인에서 32 비트 MV 라인이 진화하는 동안 역사적인 이유로 워드 포인터와 바이트 포인터는 워드의 다른 위치에 오프셋, 간접 및 링 보호 비트를 가졌습니다. 일치하지 않는 포인터 형식을 함수에 전달하면 보호 오류가 발생했습니다. 결국 MV C 컴파일러는 포인터 유형 불일치 오류가있는 코드를 처리하기 위해 많은 호환성 옵션을 추가했습니다.
일부 Honeywell-Bull 메인 프레임은 (내부) 널 포인터에 비트 패턴 06000을 사용합니다.
CDC Cyber 180 시리즈에는 링, 세그먼트 및 오프셋으로 구성된 48 비트 포인터가 있습니다. 대부분의 사용자 (링 11에서)는 0xB00000000000의 널 포인터를 가지고 있습니다. 오래된 CDC 1s 보완 시스템에서는 유효하지 않은 주소를 포함하여 모든 종류의 데이터에 대한 특수 플래그로 all-one-bits 단어를 사용하는 것이 일반적이었습니다.
이전 HP 3000 시리즈는 바이트 주소에 대해 워드 주소와 다른 주소 지정 체계를 사용합니다. 위의 여러 기계와 마찬가지로 다른 포인터보다 char * 및 void * 포인터에 대해 다른 표현을 사용합니다.
태그가 지정된 아키텍처 인 Symbolics Lisp Machine에는 기존의 숫자 포인터도 없습니다. 쌍 (기본적으로 존재하지 않는 핸들)을 C 널 포인터로 사용합니다.
사용중인``메모리 모델 ''에 따라 8086 제품군 프로세서 (PC 호환)는 16 비트 데이터 포인터와 32 비트 함수 포인터를 사용하거나 그 반대의 경우도 가능합니다.
일부 64 비트 Cray 머신은 단어의 하위 48 비트에서 int *를 나타냅니다. char *는 상위 16 비트 중 일부를 추가로 사용하여 단어 내의 바이트 주소를 나타냅니다.
추가 링크 : 이러한 컴퓨터 중 일부에 대한 자세한 내용이 포함 된 Chris Torek 의 메시지 .
원하는 것은 아니지만 16 비트 DOS / Windows 시절에는 포인터와 원거리 포인터를 구분했으며 후자는 32 비트였습니다.
구문이 잘못되었을 수 있습니다.
int *pInt = malloc(sizeof(int));
int far *fpInt = _fmalloc(sizeof(int));
printf("pInt: %d, fpInt: %d\n", sizeof(pInt), sizeof(fpInt));
산출:
핀 : 2, fpInt 4
따라서 논리적으로 sizeof(void*) >= sizeof(T*)
모든 유형 T에 대해 맞습니까?
sizeof는 스토리지 표현에 관한 것이고 모든 비트 패턴이 유효한 값일 필요는 없기 때문에 반드시 따르는 것은 아닙니다. 어디서 당신이 준수 구현을 쓸 수있는 생각 sizeof(int*) == 8
, sizeof(void*) == 4
하지만있는 int *에 대한 더 이상 32 ^ 2 이상의 수있는 값이 있습니다. 왜 원하는지 모르겠습니다.
DOS, 8088s 및 세그먼트 메모리의 황금기에는 모든 코드가 64k (한 세그먼트)에 맞지만 데이터가 여러 세그먼트에 걸쳐있을 수있는 "메모리 모델"을 지정하는 것이 일반적이었습니다. 이것은 함수 포인터가 2 바이트, 데이터 포인터, 4 바이트라는 것을 의미합니다. 누군가가 여전히 그런 종류의 기계를 위해 프로그래밍하고 있는지 확실하지 않지만 일부는 여전히 임베디드 사용에서 살아남을 수 있습니다.
함수 포인터와 다른 모든 포인터에 대해 크기가 다른 하버드 아키텍처 머신을 쉽게 상상할 수 있습니다. 예를 모른다 ...
근거리 및 원거리 포인터는 동일한 페이지 (근접 포인터) 또는 다른 페이지 (페이지 정보를 포함하기 때문에 더 큰 원거리 포인터)의 데이터를 가리킬 수 있도록 페이징 된 플래시 또는 RAM이있는 일부 임베디드 마이크로 컨트롤러에서 여전히 사용됩니다.
예를 들어, Freescale의 HCS12 마이크로 컨트롤러는 16 비트 Von Neumann 아키텍처를 사용합니다. 이는 주소가 16 비트를 초과 할 수 없음을 의미합니다. 이로 인해 사용 가능한 코드 공간의 양이 제한되므로 8 비트 페이지 레지스터가 있습니다.
따라서 동일한 코드 페이지의 데이터를 가리 키려면 16 비트 주소 만 지정하면됩니다. 이것은 가까운 포인터입니다.
다른 코드 페이지의 데이터를 가리 키려면 해당 페이지 내에 8 비트 페이지 번호와 16 비트 주소를 모두 포함해야하므로 24 비트 원거리 포인터가 생성됩니다.
예를 들어 데이터에 대한 포인터의 크기가 함수에 대한 포인터와 다를 수 있습니다. 이것은 임베디드 시스템 용 마이크로 프로세서에서 흔히 발생합니다. 언급 한 dmckee와 같은 하버드 아키텍처 머신은이를 쉽게 수행 할 수 있습니다.
gcc 백엔드를 개발하는 데 어려움을 겪는 것으로 나타났습니다! :)
편집 : 제가 이야기하고있는 특정 컴퓨터에 대한 세부 사항은 설명 할 수 없지만 Harvard 컴퓨터가이 작업을 쉽게 수행 할 수있는 이유를 추가하겠습니다. Harvard 아키텍처는 명령어와 데이터에 대한 저장과 경로가 다르므로 명령어 용 버스가 데이터 용 버스보다 '더 크다'면 데이터에 대한 포인터보다 크기가 더 큰 함수 포인터를 갖게됩니다!
'Program Tip' 카테고리의 다른 글
동일한 빌드에 대한 Jenkins 다중 아티팩트 (0) | 2020.12.15 |
---|---|
jstl로 속성이 설정되었는지 (null이 아니고 빈 문자열이 아닌지) 어떻게 확인할 수 있습니까? (0) | 2020.12.15 |
SQLServer가 불필요한 항목을 작성하는 것을 중지하는 방법 (예 : 영향을받는 행 1 개) (0) | 2020.12.15 |
Python 스레드에서 전체 애플리케이션을 종료하는 방법은 무엇입니까? (0) | 2020.12.15 |
사용자 지정 AuthorizeAttribute 클래스 내에서 RedirectToAction ()을 사용할 수 있습니까? (0) | 2020.12.15 |