Static assert
: 컴파일 타임에 assertion 을 할 수 있다.
C에서 기존에 사용하던 assert() 는 runtime 에 동작한다.
C++11에서는 컴파일 타임에도 assert을 사용하도록 static_assert 를 도입했다.
다만 사용할 때 컴파일 타임에 사용할 수 있는 연산자, 매크로, 함수 등을 사용해야 함을 주의하자.
static_assert 가 필요한 상황을 생각해보자.
예를 들어, Packet 구조체를 만들고 이 데이터가 네트워크를 통해서 전달된다면
구조체의 크기를 구하는 연산이 매우 중요하다고 할 수 있다.
하지만 intel cpu 의 경우 연산 속도를 빠르게 하기 위해서 padding 을 넣기 때문에
컴파일 후 sizeof(packet) 의 반환값이 8 이 반환된다.
(우리는 char(1) + int(4) = 5 bytes를 기대했지만..)
이런 경우, sizeof(Packet) 의 값이 개발자가 기대하는 값과 일치하지 않는다면 반드시 컴파일 타임에 에러를 내야 한다.
또한 pragma pack(1)을 넣어 padding 을 넣지 않도록 할 수도 있다.
static_assert 가 필요한 또 다른 예제를 살펴보자.
일반적으로, 객체 선언 후 초기화를 위해 memset 함수를 많이 사용한다.
하지만 위 예제에서 처럼, memset(&t, 0, sizeof(Test)); code는 문제가 없을까?
먼저 Virtual function 의 원리를 알아야 하는데,
실제 Test Class 내부 구조를 살펴보면 virtual function 을 위해서
가상 함수 table 을 가리키는 pointer가 있다.
근데 memset 을 호출하면 가상 함수 table 을 가리키는 pointer 가 0으로 초기화되므로
이후에 가상 함수를 참조하려고 하면 문제가 발생한다.
이 문제를 해결해 보자.
가상 함수가 없는 객체만 0으로 초기화하도록 static_assert 를 사용해보자.
traits 를 사용해서 가상 함수가 class 내에 있는지 확인 해서 assertion 하도록 한다.
피드 구독하기:
댓글 (Atom)
[C++] meta programing
재귀 호출에 관해 template meta programming 을 적용한 예제를 살펴보자. #include using namespace std; int fact(int n){ if(n factorial 연산을 하는 일반적인 재귀 호출 함...
-
Smart Pointer : 포인터처럼 동작하며 자동으로 메모리를 해제하고 안전하게 resource를 관리하도록 돕는 객체 포인터는 소멸자가 호출되지 않아 memory leak이 발생한다. Java, C#같은 VM이 있는 언어는 VM에서 G...
-
nullptr 란? C++11 에서 지원하는 null pointer 상수 먼저 pointer 가 초기화될 수 있는 정수 값을 살펴보자. 정수 0은 모든 타입의 포인터에 암시적 형변환을 통해서 초기화 값으로 사용될 수 있다. 하지만 그 이...
-
자료 구조를 순회하여 데이터에 접근하는 방법을 살펴보자. Container 에 저장된 데이터에 접근하기 위해 대표적으로 Iterator의 begin(), end() function 을 사용한다. 하지만 위 예제에서 show() 함수에 배열이...
댓글 없음:
댓글 쓰기