반응형

C++ Socket : 고정 구조체

알게된 배경

 기존 소켓 교재들 대부분이 C로 되어 있는것을 접하다가 C++로 옮기고 나서 소켓 프로그램을 작성할때에 구조체의 크기가 C와 같이 연속적인 형태로 메모리에 저장되지 않는다는 것을 알게 되었기에 기록으로 남긴다.


C Style Struct?

 이제는 고유 키워드가 되어 버렸다. C만 기본적으로 메모리에 직접적으로 올라가는 듯 하다. 혹은 라이브러리로 혹은 이후 표준으로 확장이 되는지 앞으로 확인이 필요할 듯하다.

 이유는 메모리에 사용자가 로드하는 대로 하지 않는 이유는 성능을 향상시키기 위해서 하는 작업이기 때문이다. 성능을 중요시한다면, 후에라도 지원이 될 듯 하지만.. C의 언어 철학은 프로그래머를 믿으라는 것이 모토이기 때문에 안될 가능성도 있다.


키워드

각 컴파일별로 선언하는 방식이 다르다. GCC 컴파일러 기준으로는 언더바로 확장된 키워드를 사용한다. __attribute__((__packed__))를  struct 와 이름 사이에 넣으면 된다.

GCC 예시)

// Header.hpp
struct __attribute__((__packed__)) SHeader
{
    char name[4];
    int32_t number;
    int32_t body_sz;
};



메모리 로드

 만약 키워드가 없을 경우에는 문자열과 숫자형을 구분하여 8바이트 단위로 메모리에 로드하게 된다. 


 예제 예시로 설명하자면, 편의상 8바이트 단위를 row라고 하면, row1에 name[4]가 로드되고 row2에 number, body_sz가 로드되어서 row가 2개이므로 총 16바이트를 차지하게 된다.

 따라서 __attribute__ 를 사용해서 실제 내부 총량이 메모리에 로드되는 것과 동일하게 하면, 12바이트가 된다(소켓 프로그램에서는 이렇게 되어야 한다).


이러한 이유로 일반적인 PC간의 소켓 통신을 할경우 헤더같이 struct로 자료형을 만들 경우 가능하면 8바이트로 딱떨어지는 형태가 되는 것이 성능저하가 적을 것이라 예측이 되는 요소이다(대부분 운영체제는 현시점에서 8바이트 형태로 최적화 되어 있는 듯 하다. 물론 이는 절대적이지 않다).


(MVC++(Microsoft Visual C++)컴파일러의 경우 다른 방법이 있는 것으로 알고 있는데, 정리할 때 메모부분을 분실해서 추후에 추가하기로 기약한다.)


여담

 C++98 이후 부터 성능을 올리기 위해서 도입이 된 것같다.

 이런식으로 언더바(_) 두개를 이용한 새로운 키워드로 기능을 확장을 하고 있는 추세이기 때문에 변수 선언시 언더바 사용을 자제할 것을 권장하고 있다. C#에서는 클래스 멤버변수를 선언시 언더바를 아직 사용하는 경향이 있지만, C++에서는 언더바 사용을 안하고 반만 헝가리식으로 소문자 m을 붙이는 경향도 있다. 어찌 되었든 권장이니 꼭 따를 필요는 없고 프로젝트 규약에 주의하자.


참고자료

스택오버 플로워


반응형

+ Recent posts