2012-06-30 2 views
4

그래서 우리는 표준이 포인터 크기를 동일하게 강제하지 않는다는 것을 알고 있습니다. (herehere) (기능 포인터에 대해 언급하지 않음)void **에서 char **로 변환하는 것은 얼마나 위험한가요?

저는 현실에서 어떻게 문제가 될 수 있는지 궁금합니다. void *은 아무 것도 저장할 수 있으므로 포인터 크기가 다른 경우 가장 큰 크기가됩니다. 따라서 void **char **에 할당하면 문제가 발생합니다.

제 질문은 void *char *이 같은 크기라고 가정하는 것이 얼마나 위험할까요? 이것이 사실이 아닌 건축물이 실제로 있습니까?

또한 16 비트 dos는 내가 듣고 싶은 것이 아닙니다! ;)

답변

9

void *char *의 크기가 동일해야합니다.

void **char **과 크기가 같을 수는 없지만 구현시 매우 유용합니다.

(C99, 6.2.5p27)이 "무효의 포인터가 캐릭터 타입에 대한 포인터와 같은 표현 및 정렬 요건을 가진다 [...] 다른 유형 포인터 같은 표현이나 정렬을 할 필요가 없다 요구 사항. " 할당은 (암시)를 포함하는 변환을 입력합니다, 그래서 (UN)과 같은 float에 할당 등의 문제가있다 : 서로 다른 개체 유형의

+0

가장 중요한 질문에 대답하십시오 .. – dcow

+0

@DavidCowden 답변을받지 못한 질문은 무엇입니까? – ouah

+0

당신은 당신의 대답을 편집 한 다음 그 질문을했습니다 .. – dcow

3

할당 포인터는 한 정렬에 대한 요구 사항이 위반되지 않습니다으로 허용된다 int - 대부분의 경우 작동하지만 의미있는 변환이 불가능할 경우에는 폭파 될 수 있습니다.

char *void *은 그래서 char **void ** 변수 (또는 그 반대)을 할당 결코 문제가, 사양에 따라 호환 정렬 요구 사항이 있습니다. 그들은 심지어 실질적으로 char *을 가리키는 void **을 dereferening하여 void * 유형의 표현을 통해 char *에 액세스하는 원칙적으로 호환 가능한 표현을 갖기 때문에 대부분의 경우 예상대로 작동합니다. 물론 역방향 (char ** 역 참조로 void *에 액세스)도 마찬가지입니다.

예를 들어 printf()의 변환 지정자 pvoid *을 예상하며 임의의 포인터 유형을 전달하는 것은 정의되지 않은 동작입니다. 그러나 char *의 경우 구현이 C 표준을 준수하는 한 이질적인 아키텍처 (예 : 다른 포인터 표현 포함)에서도 작동해야합니다.

에일리어싱 분석에 문제가 발생할 수 있습니다. 효과적인 입력 규칙으로 인해 void **char **은 별칭을 지정할 수 없으며 프로그래머가이 약속을 어기면 이상한 일이 발생할 수 있습니다. 효과적인 타이핑 (일명 엄격한 앨리어싱) 때문에 C는 실제로 강하게 타이핑됨을 인식해야합니다. 타입 시스템은 매우 불건전합니다 (즉, 불변성을 위반하지 않도록 보호하지 않습니다).

+0

그 목록 부분을 조금 더 설명해 주시겠습니까? 앨리어스가 문제를 일으키는 이유는 무엇입니까? 그것은 최적화 때문입니까? 두 개의'char **'가 서로 별칭을 지어 주겠습니까? 그렇다면, 어때? – Shahbaz

+0

@Shahbaz : 만약'void foo (char ** a, void ** b)'라는 함수를 가지고 있다면, 컴파일러는'a! = b' (* 이것은 간단하고 실제적으로 간단합니다. 거짓말*); 'a'와'b'가 모두'char ** '타입을 가지고 있다면, 컴파일러는 최적화를 제한하고'restrict'의 도입을 유도하는 가정을 할 수 없습니다; 포인터가 포인터가되는'a'와'b'와는 아무런 관련이 없다는 것을 알아 두십시오 - 만약'int *'와'float *'타입을 가지고 있다면 마찬가지입니다 – Christoph

관련 문제