Compiler Extensions: __super, __if_exists

C/C++ 컴파일러는 표준에 적합하면서도 각 벤더들만의 확장 기능이 있는데, MSVC 컴파일러에는 있는 유용한 extension들을 살짝 들여다 보자. 기억이 맞는다면 Visual Studio .NET (7.0) 부터 지원된 기능들이다. 안타깝게도 gcc에서는 아래 기능들이 지원이 안 되는 것 같다. 그러나 반대로 MSVC에서 지원하지 않는 gcc의 재밌는 키워드 __builtin_expect도 있다.


1. __super
이름에서 말하듯이 자신의 base-class를 가리키는 키워드이다. 예를 들어, overriding한 method에서 상위 클래스의 구현을 호출하고 싶으면 항상 그 상위 클래스이름::메소드이름을 사용했어야 하는데 이 키워드로 그런 불편함을 덜 수 있다 (첫 번째 예제 코드는 MSDN에서 발췌).

// deriv_super.cpp
// compile with: /c
struct B1 {
void mf(int) {}
};

struct B2 {
void mf(short) {}
void mf(char) {}
};

struct D : B1, B2 {
void mf(short) {
__super::mf(1); // Calls B1::mf(int)
__super::mf('s'); // Calls B2::mf(char)
}
};
String XEntity::GetPropertyCore(PCPROPERTY pProperty) throw(...)
{
// No overriden behaviors
return __super::GetPropertyCore(pProperty);
}

void XEntity::SetPropertyCore(PCPROPERTY pProperty, ARGString strValue) throw(...)
{
// No overriden behaviors
__super::SetPropertyCore(pProperty, strValue);
}

2. __if_exists, __if_not_exists
__super는 비교적 자주 쓸 수 있는 반면, 이 키워드는 그렇게 많이 쓰이지는 않을 것이다. 이 키워드는 특정 심볼이 컴파일 할 때, 존재하는지를 알려준다. 말 그대로 컴파일러 심볼 테이블에 있는 identifier인지를 확인 해주는 기능이다 (코드는 MSDN에서 발췌).

template
class X : public T {
public:
void Dump() {
std::cout << "In X::Dump()" << std::endl;

__if_exists(T::Dump) {
T::Dump();
}
__if_not_exists(T::Dump) {
std::cout << "T::Dump does not exist" << std::endl;
}
}
};

한 마디로 #ifdef와 유사한 기능이라고 볼 수 있다. 그러나 단순히 identifier가 아닌 클래스 멤버 변수 유무까지 알 수 있으니 상당히 유용한 경우가 많다. 특히 매크로 작성시 정말 강력한 기능을 제공할 수 있다. 자세한 매크로 예를 다 들자면 너무 복잡하고, 예를 들어, 어떤 함수가 있을 경우에만 특정 코드를 만들어주는 #define을 만들 때 상당히 유용하다. #define 안에서는 #ifdef와 같은 것을 쓸 수가 없기 때문이다. 물론 #ifdef에 따라 #define을 해줘도 되지만 불편한 경우가 많다

#define XCOMP_INIT(object_type){                        \
__if_exists (X##object_type::CreateObject){ \
X##object_type* _p = new X##object_type; \
_p->SetTypeInfo(ObjectType::object_type); \
__if_exists (X##object_type::CreatePropertyMap){\
_p->CreatePropertyMap(); \
} \
__if_exists (X##object_type::CreateEventMap){ \
_p->CreateEventMap(); \
} \
__if_exists (X##object_type::CreateMethodMap){ \
_p->CreateMethodMap(); \
} \
delete _p; \
} \
} \

부록) 여러 줄에 걸친 매크로 작성시 특히 주의 해야 할 점: '\'를 이용해서 line break를 할 수 있는데, 절대 '\' 뒤에 whitespace가 와서는 안 된다. 이 경우 친절하게 "error C2014: preprocessor command must start as first nonwhite space" 에러가 뜨는 경우도 있지만, 아주 고약한 에러가 떠서 에러를 찾는데 고생할 수 있다. 이럴 때, Visual Studio 에디터의 경우에는 [Ctrl+Shift+8]을 눌러 whitespace를 확인해봄으로써 쉽게 확인할 수 있다. 아래 그림의 경우 첫 번째 줄에서 \뒤에 공백이 하나 들어가있음을 볼 수 있다.

by object | 2007/07/21 12:20 | 컴퓨터 | 트랙백 | 핑백(6) | 덧글(3)
트랙백 주소 : http://minjang.egloos.com/tb/1352950
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Linked at 미친병아리가 삐약삐약 : 20.. at 2007/07/23 00:27

... 지 못하는 이유는 OS에 새 기능이 들어가면 C++에 가장 먼저 반영이 되기 때문.. 당연하다.. OS를 C/C++로 만들고 있으니.. Compiler Extensions: __super, __if_exists 오~ 이런 것도 있었군.. 표준은 아니지만, 윈도우즈 프로그래밍을 하면서는 참고해 볼만.. 웹 항해일지, 2007-07-21 The ... more

Linked at art.oriented : 컴.. at 2007/08/24 18:01

... M_DESTROY() END_MESSAGE_MAP() 여기서 아이디어를 얻어 다음과 같은 매크로를 만들어 보았다. 이 매크로를 만들 때 Visual C++의 compiler extension은 참 유용하였다 (간략화 한 것임): XBEGIN_PROPERTY_MAP(XComponent) XPROPERTY_ ... more

Linked at art.oriented : V.. at 2008/03/06 04:55

... 크로도 쉽게 만들 수 있다. 6. 더 훌륭해진 컴파일러컴파일러만 놓고봐도 VS 2005 이상을 써야할 이유가 충분하다. MS compiler extension이긴 하지만 편리한 키워드도 추가가 되었으며, profile-guided 최적화도 가능하고, 컴파일러 메세지도 보다 친절해졌으며, OpenMP도 그냥 지원이 된다. C99 기능들은 지원하지는 않지만 ... more

Linked at Death : Rebirth .. at 2008/03/06 09:41

... 크로도 쉽게 만들 수 있다. 6. 더 훌륭해진 컴파일러컴파일러만 놓고봐도 VS 2005 이상을 써야할 이유가 충분하다. MS compiler extension이긴 하지만 편리한 키워드도 추가가 되었으며, profile-guided 최적화도 가능하고, 컴파일러 메세지도 보다 친절해졌으며, OpenMP도 그냥 지원이 된다. C99 기능들은 지원하지는 않지만 ... more

Linked at jelly's 노트생각 : V.. at 2008/07/24 13:44

... 크로도 쉽게 만들 수 있다. 6. 더 훌륭해진 컴파일러컴파일러만 놓고봐도 VS 2005 이상을 써야할 이유가 충분하다. MS compiler extension이긴 하지만 편리한 키워드도 추가가 되었으며, profile-guided 최적화도 가능하고, 컴파일러 메세지도 보다 친절해졌으며, OpenMP도 그냥 지원이 된다. C99 기능들은 지원하지는 않지만 ... more

Linked at Dreaming Of Plat.. at 2009/08/18 15:26

... 편리한 키워드</a><a title="다음 링크를 새 창으로 엽니다. : '편리한 키워드'" style="PADDING-LEFT: 15px; BACKGROUND: url(/plugins/NewWindowLink/newwindow.gif) no-repeat 0px 50%; BORDER-TOP-STYLE: none; MARGIN-RIGHT: -0.5em; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; TEXT-D ... more

Commented by 구라마왕 at 2007/07/21 13:40
아직 고급 프로그래머가 아니여서 그런지.. 이런 기능들이 확 와닿지가 않아요..
하지만 언젠가 성능이나 소스의 깜끔성을 추구하다 보면 이런 기능들 쓸 날이 오겠죠^^;;

근데 __super기능은 머가 좋은거죠? 클래스 이름 대신에 super라고 쓰면 읽기 더 불편하고 나중에 super 단어가 많아지면 그것도 좀 골치일 것 같아요;; ㅎㅎㅎ
Commented by object at 2007/07/21 14:03
말씀대로 컴파일러 익스텐션 자체가 확 와닿는 기능들은 아닙니다. 그렇게 되면 너무 남발하게 되고 결국 특정 플랫폼(컴파일러)에만 돌아가는 코드가 만들어지겠죠. 많이 쓰는 것도 결코 좋은 것이 아닙니다.

void XEntity::SetPropertyCore(PCPROPERTY pProperty, ARGString strValue) throw(...)
{
__super::SetPropertyCore(pProperty, strValue);
}

여기 예에서 __super를 보면 이렇게 생각하시면 됩니다. "XEntity 클래스의 베이스 클래스의 구현을 호출해라" 입니다. __super가 좋은 점은 XEntity의 베이스 클래스 이름을 직접 써줄 필요가 없다는 점이죠.

그리고 만약 베이스 클래스가 바뀌었을 때, 이 코드를 고칠 필요도 없다는 것도 장점입니다. 실제로 MFC 같은 경우 CWnd로 상속받았다가 나중에 CEdit 등으로 바꾸고 싶다고 할 때, __super가 없으면 CWnd::인 부분을 다 고쳐줘야 합니다. 물론 refactoring 기능이나 간단히 find/replace로 할 수도 있지만, 직접 이름을 기술하기 보다는 '관계'라는 추상화된 키워드를 사용함으로써 코드에 집중할 수 있게 만듭니다.

이런 것을 꼭 써야 한다는 것이 아니라 이런 것도 있다라고만 알아두시면 됩니다. ㅎㅎ
Commented by KIRBY at 2009/05/08 11:12
조쿤여...ㅎㅎ

:         :

:

비공개 덧글

<< 이전 페이지 다음 페이지 >>





by 김민장 2008 이글루스 TOP 100
최근 등록된 덧글
개발자 입장에서의 수많은 ..
by Jiyoon at 02/04
저도 아들 돌잔치때 돌잡이 ..
by 박상욱 at 01/18
미국 대학원 원서 작성중에 p..
by 태클사이야 at 01/13
TO: 박PD 로그인 하지 않아..
by 박응용 at 01/10
http://gigglehd.com/zbx..
by dhunter at 12/28
우와.. 좋네요. 태반이 ..
by 윤광배 at 12/17
항상 좋은 글 잘 보고 있습니..
by y2k at 11/23
글이 좋아서 제 블로그에 담..
by 쏭섭 at 11/23
최근 등록된 트랙백
조엘 스폴스키의 강연 (Sta..
by 인덕원칸타타
[Redis] sds.c를 분..
by 조급하지말고 천천히
메뉴릿
이글루 파인더

website counter

Add to Google

rss

skin by 이글루스