최종 결론 : 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*
편집자 주 : 이 답변은 최종 결론을 반영하기 위해 편집되었습니다.