특정 유형 (예 int
: char
,, float
..)에 대한 포인터 가 증가하면 해당 데이터 유형의 크기만큼 값이 증가합니다. 경우 void
크기의 데이터에 대한 포인터하는 포인트가 x
증가 점에, 어떻게 나올까요 x
앞서 바이트? 컴파일러 x
는 포인터의 가치 를 높이는 방법을 어떻게 알 수 있습니까?
답변
최종 결론 : a에 대한 산술 void*
은 C와 C ++에서 모두 불법 입니다.
GCC는이를 확장으로 허용합니다. 산술 void
및 함수 포인터를 참조하십시오 (이 섹션은 설명서의 “C 확장”장의 일부입니다). Clang과 ICC void*
는 GCC와의 호환성을 위해 산술을 허용 할 것 입니다. 다른 컴파일러 (MSVC와 같은)는에 대한 산술을 허용하지 void*
않으며 GCC는 -pedantic-errors
플래그가 지정되거나 플래그가 지정된 경우이를 허용하지 않습니다 -Werror-pointer-arith
(이 플래그는 코드베이스도 MSVC로 컴파일해야하는 경우에 유용합니다).
C 표준은 말한다
따옴표는 n1256 초안에서 가져옵니다.
추가 작업 상태에 대한 표준 설명 :
6.5.6-2 : 또한 두 피연산자 모두 산술 유형을 갖거나 한 피연산자는 객체 유형에 대한 포인터이고 다른 피연산자는 정수 유형이어야합니다.
따라서 여기서 질문 void*
은 “객체 유형”에 대한 포인터인지 또는 “객체 유형”인지 void
에 대한 것입니다. “객체 유형”의 정의는 다음과 같습니다.
6.2.5.1 : 유형은 객체 유형 ( 객체 를 완전히 설명하는 유형), 함수 유형 (함수를 설명하는 유형) 및 불완전한 유형 (객체를 설명하지만 크기를 결정하는 데 필요한 정보는없는 유형)으로 분할됩니다 .
그리고 표준은 다음 void
과 같이 정의 됩니다.
6.2.5-19 :
void
유형은 빈 값 집합으로 구성됩니다. 완료 할 수없는 불완전한 유형입니다.
void
불완전한 유형 이므로 객체 유형이 아닙니다. 따라서 추가 연산에 유효한 피연산자가 아닙니다.
따라서 포인터에서 포인터 산술을 수행 할 수 없습니다 void
.
노트
원래 void*
C 표준의 다음 섹션으로 인해 산술이 허용되는 것으로 생각 되었습니다.
6.2.5-27 : void에
대한 포인터는 문자 유형에 대한 포인터 와 동일한 표현 및 정렬 요구 사항을 가져야 합니다 .
하나,
동일한 표현 및 정렬
요구 사항은 함수에 대한 인수, 함수의 값 반환 및 공용체 멤버와의 호환성을 의미합니다.
따라서 이것은 유형 또는 유형에 printf("%s", x)
관계없이 동일한 의미를 갖지만,에 대해 산술을 수행 할 수있는 것은 아닙니다 .x
char*
void*
void*
편집자 주 : 이 답변은 최종 결론을 반영하기 위해 편집되었습니다.
답변
포인터에는 포인터 산술이 허용되지 않습니다 void*
.
답변
포인터를 x 바이트 앞으로 앞으로 증가시키는 char 포인터로 캐스트하십시오.
답변
C 표준은 허용하지 않습니다 무효 포인터 연산을. 그러나, GNU C는 의 크기를 고려하여 허용 무효 IS를 1
.
C11 표준 §6.2.5
단락-19
void
유형 값의 빈 세트를 포함하고; 그것은이다 불완전한 개체 유형 을 완료 할 수 없습니다.
다음 프로그램은 GCC 컴파일러에서 정상적으로 작동합니다.
#include<stdio.h>
int main()
{
int arr[2] = {1, 2};
void *ptr = &arr;
ptr = ptr + sizeof(int);
printf("%d\n", *(int *)ptr);
return 0;
}
다른 컴파일러가 오류를 생성 할 수 있습니다.
답변
void *
정확히 이런 이유로 타입에 대한 포인터 산술을 할 수 없습니다 !
답변
포인터 산술을 수행하기 전에 다른 유형의 포인터로 캐스트해야합니다.
답변
무효 포인터는 메모리 청크를 가리킬 수 있습니다. 따라서 컴파일러는 void 포인터에서 포인터 산술을 시도 할 때 증가 / 감소 할 바이트 수를 알지 못합니다. 따라서 void 포인터는 포인터 산술에 관여하기 전에 먼저 알려진 형식으로 타입 캐스트해야합니다.
void *p = malloc(sizeof(char)*10);
p++; //compiler does how many where to pint the pointer after this increment operation
char * c = (char *)p;
c++; // compiler will increment the c by 1, since size of char is 1 byte.