동작이 잘 정의되어있는 것은 사실이지만 그렇지 않습니다. 있다는 사실이지만 컴파일러가 의미하는 바에 따라 "const를 최적화"할 수 .
즉, 컴파일러가되어 있지 허용 매개 변수가를 단지 때문에 가정 const T* ptr
에 의해, 메모리는 지적 ptr
다른 포인터를 통해 변경되지 않습니다. 포인터가 같을 필요도 없습니다. 그만큼const
보증이 아니라 의무입니다. 해당 포인터를 통해 변경하지 말아야 할 의무는 사용자 (= 기능)입니다.
실제로 그러한 보증을 받으려면 restrict
키워드로 포인터를 표시해야 합니다. 따라서이 두 함수를 컴파일하면
int foo(const int* x, int* y) {
int result = *x;
(*y)++;
return result + *x;
}
int bar(const int* x, int* restrict y) {
int result = *x;
(*y)++;
return result + *x;
}
foo()
기능은 두 번에서 읽을 수 있어야 x
하지만, bar()
한 번만 읽을 필요가 :
foo:
mov eax, DWORD PTR [rdi]
add DWORD PTR [rsi], 1
add eax, DWORD PTR [rdi] # second read
ret
bar:
mov eax, DWORD PTR [rdi]
add DWORD PTR [rsi], 1
add eax, eax # no second read
ret
이 라이브를 참조하십시오 GodBolt.
restrict
C의 키워드입니다 (C99 이후). 불행히도, 지금까지 C ++에 도입되지 않았습니다 (C ++에서 도입하기가 더 어려운 열악한 이유로). 그러나 많은 컴파일러가이를 지원합니다.__restrict
.
결론 : 컴파일러는 컴파일 할 때 "비밀"사용 사례를 지원해야하며 f()
문제가 발생하지 않습니다.
의 사용 사례에 대해서는 이 게시물을 참조하십시오 restrict
.
const
"포인터를 통해 변경을하지 말아야 할 의무"(= 기능)가 아닙니다. C 표준은 함수가const
캐스트를 통해 제거 하고 결과를 통해 객체를 수정하도록 허용합니다 . 본질적으로,const
의도하지 않은 객체 수정을 피하기 위해 프로그래머에게 조언과 편의를 제공합니다.