C의 이중 포인터 연속성 경고
비정수 데이터에 대한 포인터는 같은 유형의 데이터를 구성하기 위한 포인터로 암묵적으로 변환할 수 있습니다.
int *x = NULL;
int const *y = x;
추가 간접과 일치하도록 추가 Const 수식자를 추가하는 것도 논리적으로 동일하게 동작해야 합니다.
int * *x = NULL;
int *const *y = x; /* okay */
int const *const *z = y; /* warning */
GCC 또는 Clang을 사용한 컴파일-Wall
단, 플래그가 발생하면 다음 경고가 발생합니다.
test.c:4:23: warning: initializing 'int const *const *' with an expression of type
'int *const *' discards qualifiers in nested pointer types
int const *const *z = y; /* warning */
^ ~
왜 추가가const
한정자 "네스트된 포인터 유형에 한정자 포함?"
이유const
는 1레벨만 추가할 수 있으며 미묘하며 comp.lang.c FAQ의 질문 11.10에서 설명합니다.
간단히 말하면, 이 예는 고객의 예와 밀접하게 관련되어 있습니다.
const int i;
int *p;
int const **z = &p;
*z = &i;
/* Now p points to i */
C는 할당이 첫 번째 포인트 투 레벨에서 한정자를 폐기하는 것만을 허용함으로써 이 문제를 회피합니다(따라서 할당은z
여기에는 사용할 수 없습니다).
이 예에서는 이 문제가 발생하지 않습니다.const
두 번째 레벨은 에의 할당이*z
어차피 허락되지 않을 거야C++는 이 경우 그대로 허용되지만 C의 단순한 규칙은 대소문자와 위의 예를 구분하지 않습니다.
다른 답변과 링크된 FAQ 항목은 다음 코드가 허용되지 않는 이유를 설명합니다.
int **x = whatever;
const int **z = x;
단, 고객님의 코드는const int *const *z = x;
상당히 다르며 FAQ에서 제기된 것과 같은 결함을 겪지 않습니다.
사실 후자 코드에는 개념적으로 문제가 없습니다.이는 허용되지 않는 C 사양의 결함일 뿐이며 C 프로그래머가 코드에 추악한 캐스트를 포함하도록 강제합니다.
C가 C++와 같은 규칙을 사용하는 것은 가능했지만, C 표준 위원회는 그렇게 결정하지 않았습니다.
수식자 추가 자동화가 첫 번째 간접 수준에서만 작동하는 이유는 표준에서 확인할 수 있습니다.
6.5.16.1의 기준은 "양쪽 피연산자 모두 호환 가능한 유형의 적격 또는 부적격 버전에 대한 포인터이며, 왼쪽이 가리키는 유형은 오른쪽이 가리키는 유형의 모든 한정자를 가진다"고 주장한다.
이 문장의 마지막 부분은 가리키는 글자에 한정자를 추가하는 것이 문제없다는 것을 의미합니다.
그리고 첫 번째 부분은 "호환 가능한" 유형이라고 주장합니다.그리고 (내 생각에) 6.7.3 (11)은 적격 유형에 대해 다음과 같이 기술한다. "적격된 두 유형이 호환되려면 양쪽이 호환 가능한 유형의 동일한 적격 버전을 가져야 한다."
이것을 읽어 보면, 지적된 타입은 호환성이 없는 것으로 간주됩니다(한쪽을 다른 쪽에 할당할 수 있는 경우라도).
따라서 수식자 폐기에 대한 clang 경고는 다소 오해의 소지가 있지만 동일하지 않은 수식자 지정 유형을 가리킵니다.
언급URL : https://stackoverflow.com/questions/5055655/double-pointer-const-correctness-warnings-in-c
'programing' 카테고리의 다른 글
VueX: 중첩된 객체를 사용하여 스토어를 구성하는 방법 (0) | 2022.08.29 |
---|---|
lamda 표현식은 실행될 때마다 힙에 개체를 생성합니까? (0) | 2022.08.29 |
지도에서 반복 제거 (0) | 2022.08.29 |
새로운 요소/컴포넌트를 동적으로 추가하려면 appendChild와 동등한 Vue.js를 선택하십시오. (0) | 2022.08.29 |
VueJs 2클릭이 작동하지 않는 것 같다 (0) | 2022.08.29 |