는, GCC는 유형이 당신의 예와 const double * const * const * d
모두 다르기 때문에 경고를 생성합니다. C++에서는 OP 코드에 오류가 있지만 slap-const-everywhere 방식이 적합합니다.
컴파일러가 경고하는 이유는 포인터 (또는 추가 간접 참조)에 대한 포인터가 매개 변수가 가리키는 위치를 수정하여 호출자에게 포인터를 반환 할 수있게한다는 것입니다.
포인터의 대상이 const로 선언 된 경우 호출 된 함수는 반환 할 때 const로 처리되도록 값을 예상합니다.
이 에러가 될 이유 나타내는 const T**
에 T**
를 전달하는 간단한 경우 : C
에
void foo (const char ** z)
{
*z = "A";
}
int main (int nargs, char** argv)
{
char* z = 0;
char** d = &z;
// warning in C, error in C++
foo (d);
// bad - modifies const data
z[0] = 'Q';
}
const
데이터가 변경하지 않을 것을 의미한다. C++의 const
은 데이터가 공개적으로 변경되지 않는다는 것을 의미합니다. C++ 객체의 변경 가능한 데이터가 변경 될 수 있습니다. AC 컴파일러는 코드를 최적화하여 const
데이터를 어딘가에 캐시 할 수 있지만 C++ 컴파일러는 가능한 mutablity 때문에 그렇게 할 수 없으므로 위와 같이 const가 아닌 데이터로 const 데이터를 반환 할 수 없다는 약한 제약이 있습니다. . 따라서 C++에서 double***
은 const
이 수정 불가능한 메모리의 반환을 막기 때문에 const double * const * const * d
으로 캐스팅 될 수 있지만 컴파일러가 메모리에 반복적으로 액세스하는 것을 최적화하면 C에서 경고 및 가능한 오류가 발생합니다.
에 C 및 C++로 태그가 지정된 질문이있는 경우 오류 란 무엇이고 허용되는 규칙은 혼란을 일으킬 수 있습니다. –
@Pete 당신 말이 맞아요. 이 예제에서는 usigng C 컴파일러입니다. 이와 관련하여 규칙이 정말로 다른가요? – vehomzzz