2011. 12. 9. 10:23 윈도우/참고
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를 확인해봄으로써 쉽게 확인할 수 있다. 아래 그림의 경우 첫 번째 줄에서 \뒤에 공백이 하나 들어가있음을 볼 수 있다.


출처 : http://minjang.egloos.com/1352950
posted by townone