[Hive Helsinki / 42cursus] restrict pointer와 size_t type
42 cursus에 접어들고, 첫 번째 과제인 Libft을 수행하면서 memcpy 함수를 구현하던 중 restrict pointer와 size_t type을 처음 접하게 되었다. size_t type은 이전에도 strlen 등의 매뉴얼 등을 확인하며 본 경험이 있으나 사용해 본 적은 없고, restrict pointer는 처음 보아서 좀 더 기록해보려 한다.
restrict pointer
restrict 키워드는 메모리 접근을 최적화하기 위해서 사용된다. restrict 키워드가 쓰였다면 각 변수가 같은 메모리 공간이 아니라는 것을 컴파일러에게 알려주려는 것이다. 나도 이런 설명만 봐서는 대체 무슨 말인지 이해가 되지 않았다. 그래서 내가 본 memcpy 함수의 프로토타입과 함께 이야기 하려 한다. 아래는 memcpy 함수의 매뉴얼에 기재되어 있는 프로토타입이다.
void *memcpy(void *restrict dst, const void *restrict src, size_t n)
여기서 보면 dst와 src 인자가 restrict pointer로 설정되어 있다. 간단히 설명하면 src에 있는 정보를 dst에 n byte만큼 옮겨 넣어야 하는 함수이다. 따라서 dst와 src에 같은 메모리 공간이 들어가서는 안될 것이다. 왜냐하면 그렇게 되면 overlap이 발생하여 복사가 제대로 실행되지 않을 수 있기 때문이다. 따라서 dst와 src에는 다른 메모리 공간이 들어가야 한다. 따라서 메모리 공간이 겹치지 않는 것을 보장하고자 적는 키워드가 restrict인 것이다.
즉, 아래 코드에서 첫 번째 경우는 가능하지만, 두 번째 경우는 불가능하다. restrict 키워드가 있는 dst와 src 인자에 같은 메모리 공간이 들어가면 안되는데, 두 번째 경우에는 str2라는 같은 메모리 공간이 두 번 들어갔기 때문이다.
int main()
{
char str1[10];
char str2[10] = "apple";
memcpy(str1, str2, sizeof(char) * 6); // (o)
memcpy(str2, str2, sizeof(char) * 6); // (x)
}
그리고 비슷한 가능을 수행하는 memmove 함수에는 restrict 키워드가 들어가지 않는다. memmove는 함수 내에 overlap에 대한 대비가 되어 있기 때문에 메모리 공간이 겹쳐도 상관이 없다.
size_t type
size_t type은 간단히 말하면 어떤 타입의 사이즈든지 나타낼 수 있는 충분한 byte를 가진 unsigned int 타입이라고 할 수 있다. 주로 메모리나 문자열 등의 길이를 구할 때 사용한다. 내가 size_t 타입을 본 적은 있지만, 한 번도 사용해 본 적이 없는 이유는 unsigned int 타입을 써왔기 때문이다.
그렇다면 둘 간의 차이는 무엇이고, 왜 메모리나 문자열 등의 길이를 구할 때에는 unsigned int type 대신 size_t를 사용할까? 이유는 size_t가 모든 타입의 사이즈에 상응하는 용량을 저장할 수 있고, 의도한 size를 보장받을 수 있기 때문이다. 의도한 size를 보장받을 수 있다는 것의 의미는 꼭 운영체제에 따르지 않는 unsigned int와는 달리 size_t는 32비트 운영체제에서는 부호 없는 32비트로, 64비트 운영체제에서는 64비트 운영체제로 보장받을 수 있다.
size_t 타입의 경우 unsigned int처럼 그냥 사용할 수 있는 것은 아니고, <stddef.h> 헤더를 include해야 사용이 가능하다.