programing

C의 이중 포인터 연속성 경고

bestcode 2022. 8. 29. 22:12
반응형

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

반응형