2016-06-26 4 views
4

다음 시나리오에서 정의되지 않은 동작이 있습니까?const 포인터가 가리키는 값을 수정하는 정의되지 않은 동작입니까

void do_stuff(const int *const_pointer, int *pointer) { 
    printf("%i\n", *const_pointer); 
    *pointer = 1; 
} 

int data = 0; 
do_stuff(&data, &data); 

이 컴파일러는 const_pointer 점은 절대 변경하는 것을 그 값을 가정하면 아마 문제를 일으킬 수 정의되지 않은 동작 인 경우. 이 경우 do_stuff에서 두 명령의 순서가 바뀌므로 의도 한 printf("0")에서 printf("1")으로 동작이 변경 될 수 있습니다.

+2

아니요. 'const'는이 방식으로 작동하지 않습니다. 만약 그렇다면 그것은 완전히 쓸모없는 것보다 더 나쁠 것입니다. 포인터에 대한'const'는이 포인터를 통해 객체를 변경할 수 없다는 것을 의미하며, 전혀 변경할 수 없다는 것을 의미하지는 않습니다. –

+0

@ n.m. 컴파일러에게 "포인터로 가리키는 데이터가 초기화되었고 다시 수정되지 않을 것이라고 약속하는 방법을 사용하는 것이 유용 할 때가 있습니다. 예를 들어 같은 표현식이 함수에서 여러 번 계산되는 경우 , 그리고 컴파일러는 표현식의 입력이 참으로 일정하다면 컴파일러가 한 번만 계산되도록 할 수 있습니다. 당신이 'const'가 이런 방식으로 작동하지 않는다는 것이 옳은 동안, 나는 그것이 "완전히 쓸모없는 것"보다 "나쁜 것"이라고 생각하지 않는다. – hvd

+2

@hvd : C99의 '제한'이 이에 해당합니다. 정확하게 (개념은 더 일반적입니다), 그러나'const'와 함께이 효과를 또한 의도합니다. – AnT

답변

2

컴파일러가 const에 대한 포인터 값 포인터가 변경되지 않는다는 것을 증명하면 값을 다시로드하거나 순서를 유지할 필요가 없다는 것을 알 수 있습니다.

이 경우 두 포인터가 별칭이 될 수 있기 때문에이 작업을 수행 할 수 없으므로 컴파일러는 포인터가 동일한 개체를 가리 키지 않는다고 가정 할 수 없습니다. 함수에 대한 호출이 다른 번역 단위에서 수행되었을 수 있으므로 컴파일러는 함수에 전달 된 내용을 알 수 없습니다.

예제에 정의되지 않은 동작이 없으므로 printf가 출력은 0입니다.

0

const_pointer은 단순히 가리키는 데이터를 변경할 수 없음을 의미합니다.

함수에 대한 포인터를 전달할 때는 const인지 여부를 전적으로 결정해야합니다. const은 원하지 않는 데이터 변경을 방지 할 수있는 보호 도구입니다. 그러나 const이 없으면 함수가 계속 작동 할 수 있습니다.

strcpy(char *s, const char *t); 

또는

strcpy(char *s, char *t); // without const, still work, just not as good as the first version

그래서이 코드에서 예상치 못한 아무것도하지해야합니다 : 당신은을 통해 데이터를 수정할 수 없습니다 예를 들어, strcpy 당신의 자신의 버전은 하나 같이 쓸 수있다 const_pointer이지만 두 포인터가 같은 위치를 가리키는 경우에도 pointer을 통해 수정할 수 있습니다.

관련 문제