구조체에 대한 모든 포인터가 동일한 크기여야 하는 이유는 무엇입니까?
C 표준은 다음을 명시합니다.
공백에 대한 포인터는 문자 유형에 대한 포인터와 동일한 표현 및 정렬 요구사항을 가져야 합니다.마찬가지로 호환되는 유형의 정규 또는 비정규 버전에 대한 포인터는 동일한 표현 및 정렬 요구사항을 가져야 합니다.구조물 유형에 대한 모든 포인터는 서로 동일한 표현 및 정렬 요구사항을 가져야 합니다.조합 유형에 대한 모든 포인터는 서로 동일한 표현 및 정렬 요구사항을 가져야 합니다.다른 유형에 대한 포인터가 동일한 표현 또는 정렬 요구 사항을 가질 필요는 없습니다.
, sizeof(int*)
반드시 다음과 같은 것은 아닙니다.sizeof(char*)
- 그러나sizeof(struct A*)
는 반드시 다음과 같습니다.sizeof(struct B*)
.
이 요구 조건의 근거는 무엇입니까?기본 유형별로 크기가 다른 이유는 이해합니다. 근/원/huge 포인터와 같은 사용 사례를 지원하는 것입니다. (편집: 의견과 답변에서 지적된 바와 같이, 이것은 근거가 아닙니다.) - 하지만 이와 같은 근거가 적용되지 않습니까?struct
기억 속의 다른 장소에 s가 있습니까?
답은 매우 간단합니다.struct
그리고.union
유형은 불투명 유형으로 선언될 수 있습니다. 즉, 실제 정의 없이.struct
아니면union
세부 사항. 포인터의 표현이 구조의 세부사항에 따라 달랐다면 컴파일러는 인수, 반환 값, 심지어는 메모리에서 읽거나 저장하는 불투명한 포인터에 어떤 표현을 사용할지 어떻게 결정할 것인가요?만약 포인터의 표현이 구조의 세부사항에 따라 다르다면, 컴파일러는 인수로 나타나는 불투명한 포인터에 어떤 표현을 사용할지 결정하거나 값을 반환하거나 심지어는 메모리에서 읽거나 저장하는 것을 어떻게 결정할까요?
불투명 포인터 유형을 조작하는 능력의 자연스러운 결과는 모든 그러한 포인터가 동일한 표현을 가져야 한다는 것입니다.그러나 이 포인터는 다음을 가리킵니다.struct
에 대한 지침.union
다음과 같은 기본 유형에 대한 포인터뿐만 아니라 다른 표현을 가질 수 있습니다.char
,int
,double
...
포인터 표현과 관련된 또 다른 차이점은 데이터에 대한 포인터와 함수에 대한 포인터 사이의 차이이며, 크기가 다를 수 있습니다.이러한 차이는 운영 체제 및 장치 드라이버 공간 밖에서는 드물지만 현재 아키텍처에서는 더 흔합니다. 함수 포인터의 경우 64비트가 코드 공간을 위해 4GB로 충분해야 하므로 낭비되는 것처럼 보이지만 현대 아키텍처에서는 이 여분의 공간을 이용하여 포인터 서명을 저장하여 악성 공격에 대한 코드를 강화합니다.다른 용도는 포인터 비트 중 일부를 무시하는 하드웨어(예: x86_64는 상위 16비트를 무시함)를 이용하여 유형 정보를 저장하거나 수정되지 않은 NaN 값을 포인터로 사용하는 것입니다.
또한 기존 16비트 코드의 near/far/highbor 속성은 모든 포인터가 near, far 또는 highbor일 수 있기 때문에 C 표준의 이 언급에 의해 정확하게 다루지 못했습니다.그러나 혼합된 모델 코드에서 코드 포인터와 데이터 포인터의 구별은 이것에 의해 다루어 졌으며 일부 OS에서는 여전히 최신인 것으로 보입니다.
마지막으로, 포식스는 모든 포인터의 크기와 표현이 동일하므로 혼합 모델 코드는 빠르게 역사적 호기심이 되어야 한다고 요구합니다.
데이터 유형별로 표현이 다른 아키텍처는 요즘 거의 없어지기 때문에 표준을 정리하고 이 옵션을 제거해야 할 때가 된 것은 분명합니다.주요 반대 사항은 어드레싱 가능한 단위가 큰 단어이고 8비트 바이트가 추가 정보를 사용하여 어드레싱되는 아키텍처에 대한 지원입니다.char *
그리고.void *
일반적인 포인터보다 큽니다.그러나 이러한 아키텍처는 포인터 산술을 매우 번거롭게 만들고 매우 희귀합니다(개인적으로 한 번도 본 적이 없습니다).
Dennis Ritchie에 의해 발명된 C 언어에서, C 컴파일러가 다음에 대한 정의를 접했을 때.struct foo *p;
그것은 프로그램이 포인터 산술을 사용하지 않는 한 또는 그 구조가 어떻게 정의되었는지에 대해 신경쓸 필요가 없을 것입니다.->
교환입니다.그렇지 않으면, 그것은 단순히 다음과 같이 기록할 수 있습니다.p
태그가 있는 구조물의 포인터였어요foo
그러한 구조가 정의될 수 있는지, 어디서 또는 어떻게 정의될 수 있는지 또는 신경쓰지 않아도 됩니다.이 표준은 가끔 일치하는 태그가 있는 구조 포인터를 호환되지 않게 만드는 이상한 작은 주름을 추가하지만, 컴파일러가 구조의 내용을 모르는 경우에 그러한 포인터 간의 기본 할당뿐만 아니라 포인터 간의 선언을 처리할 수 있어야 한다는 문제가 남아 있습니다.
임의의 정렬을 가진 객체에 대한 포인터가 다음을 가진 것으로 알려진 객체에 대한 포인터보다 클 수 있는 플랫폼에서는int
정렬, 컴파일러는 모든 구조가 다음을 가지는 것을 감각적으로 지정할 수 있습니다.int
문자 구성원만 포함된 경우에도 정렬을 수행할 수 있습니다.또한 이러한 플랫폼의 컴파일러는 모든 객체에 대한 포인터(심지어 문자)를 해당 객체를 포함하는 모든 유니언에 대한 포인터로 변환하여 유니언 내에서 해당 객체에 액세스하는 데 사용할 수 있도록 유니언에 대한 포인터를 처리하기로 결정할 수 있습니다.이를 위해서는 연합 개체에 대한 포인터가 더 작은 int 포인터가 아니라 바이트 포인터 크기여야 할 수 있습니다.
사전 표준 컴파일러에서 두 구조가 일치하는 멤버를 포함하는 경우, 다음을 수용하는 함수가void*
그리고 그것을 하나의 구조 유형으로 변환하면 두 유형 모두에서 상호 교환적으로 작동할 수 있을 것으로 예상됩니다.불행하게도, 이 표준은 컴파일러들이 코드가 결코 그런 일을 하지 않을 것이라고 가정할 수 있도록 허용하며, 프로그래머들이 언제 두 구조를 서로 교환하여 사용할 수 있어야 하는지를 나타낼 수 있는 수단을 제공하지 않습니다.
언급URL : https://stackoverflow.com/questions/68718097/why-must-all-pointers-to-structs-be-of-the-same-size
'it-source' 카테고리의 다른 글
regexp_substr Maria가 있는 문자열에서 마지막 날짜를 추출하려면 어떻게 해야 합니까?DB (0) | 2023.10.28 |
---|---|
JQuery는 다른 자바스크립트에서 AJAX 호출을 들을 수 있습니까? (0) | 2023.10.28 |
ASP.NET jQuery Ajax 호출 코드 비하인드 메서드 (0) | 2023.10.28 |
Oracle sql 병합을 삽입 및 삭제하지만 업데이트하지 않음 (0) | 2023.10.28 |
bloginfo('template_url') 또는 echo esc_url( get_template_directory_uri()) 중 템플릿 디렉토리의 URL을 검색하는 더 나은 방법은 무엇입니까? (0) | 2023.10.28 |