C언어/C언어 심화 & 특수

[C99] 포인터 최적화를 위한 restrict 키워드

카루-R 2020. 3. 21. 10:08
반응형

 이 키워드가 추가됨에 따라 , 에서도 알 수 있듯 대부분의 표준 라이브러리 함수들에 restrict가 붙었습니다.

최적화 키워드 중 하나인데, restrict을 쓰면 그 포인터가 가르키는 객체는 다른 포인터가 가르키지 않는다는 것을 나타냅니다. 주로 함수의 매개변수로 쓸 텐데, 예시를 보시죠.

#include <stdio.h>

int int_swap(int* restrict p1, int* restrict p2) {
    if (p1 == p2) return EOF;
    
    int temp = *p1;
    *p1 = *p2;
    *p2 = temp;
    return 0;
}

int main()
{
    int a = 10, b = 5;
    printf("a = %d, b = %d\n", a, b);
    
    int_swap(&a, &b);
    
    printf("a = %d, b = %d\n", a, b);

    return 0;
}

포인터를 배우면 한 번씩은 만들고 넘어간다는 swap 함수입니다. restrict는 다음과 같이 선언합니다.

void * restrict ptr;

*은 반드시 자료형과 restrict 사이에 위치해야 합니다. void restrict* ptr 이런 건 없습니다. 오류납니다.

int int_swap(int* restrict p1, int* restrict p2) {

여기서 restrict를 사용했습니다. 이 말은 즉, p1가 가르키는 객체와 p2가 가르키는 객체는 서로 다르다는 뜻 입니다. 이를 통해 컴파일러에서는 두 값이 같은지 비교할 필요가 없습니다. 따라서 컴파일러의 최적화 작업을 도와주게 됩니다. 다만 함수를 호출할 때 int_swap(&a, &a) 이렇게 호출한다면 무슨 일이 일어날 지 모릅니다. 정의되지 않은 동작입니다.

int printf(const char *restrict _Fmt [, arg...]);
int scanf(const char *restrict _Fmt [, arg...]);
char *strcpy(char *restrict _Dest, const char *restrict _Src);

당장 자주 사용하는 printf()와 scanf()만 봐도 restrict가 적용된 것을 볼 수 있습니다. restrict 포인터는 사용자에게 같은 변수의 주소를 넘기지 말라는 뜻으로도 볼 수 있습니다.

반응형