VC에서 _MSC_VER를 이용해 컴파일러에 따른 특성을 적용하는 방법
_MSC_VER를 이용한
VC에서는 _MSC_VER라는걸로 컴파일러 버전이 정의되어있으므로, 이를 이용할 수 있다.
#if _MSC_VER >= 1500
// VC9, VC 2008
#elif _MSC_VER >= 1400
// VC8, VC 2005
#elif _MSC_VER >= 1310
// VC7.1, VC 2003
#elif _MSC_VER > 1300
// VC7, VC 2002
#elif _MSC_VER > 1200
// VC6, VC 6.0
#elif _MSC_VER > 1000
// VC5, VC 5.0
#endif
이 버전은 cl.exe /?를 했을 때 표시되는 버전의 앞부분을 보면 된다. 예를 들어, VS2008SP1의 경우 "15.00.30729.01(80x86)"와 같이 표시되는데 앞의 숫자 4개인 1500이 _MSC_VER가 된다.
(더 자세한 설명이나 예제는 구글링으로 쉽게 얻을 수 있으므로 생략한다.)
똑같은것만 쓰면 의미가 없으므로(?), 나는 좀 다른짓을 해보겠다.
안전한 함수와 warning C4996
VS2005부터는 안전한 함수라는것이 추가되면서, 이전 코드를 빌드했을 때 warning C4996를 내도록 변경되었다. 주1
경고가 나는게 영~ 거슬리는데, 그렇다고 안전한 함수로 다 바꿔버리면 예전 컴파일러에서는 안돌아가게되는 문제가 생긴다. 그래서 꼼수로 다음과같은 코드를 고려할 수 있다.
#if _MSC_VER < 1300
#define strcat_s(DES, MAXDESLEN, SRC) strcat((DES), (SRC))
#endif
이렇게 하면 쓸때는 항상 안전한 함수 형식을 쓰고, 컴파일러에서 안전한 함수를 지원하지 않을 경우에는 기존 함수를 사용하도록 할 수 있다.
이 방법의 단점은, 컴파일러에 따라 프로그램의 동작이 달라진다는 점이다. 만약 des의 공간이 충분하지 않으면, 안전한 함수를 지원하는 컴파일러에서는 나머지를 무시하지만, 안전한 함수를 지원하지 않는 컴파일러에서는 buffer overflow 문제를 일으키게된다.
c++이라면 inline을 이용해서 다음처럼 만들 수도 있다.
#if _MSC_VER < 1300
inline errno_t strcat_s(char *des, size_t maxdeslen, const char *src) {
if ((des == NULL) || (src == NULL)) {
return EINVAL;
}
if ((maxdeslen <= 0) || (strlen(src) > (maxdeslen - strlen(des)))) {
return ERANGE;
}
(void) strcat(des, src);
return 0;
);
#endif
아마 실제 strcat_s()의 구현도 이와 비슷하지 않을까 싶다.
참고로 위 inline 코드는 알고리즘만 표현한거지 검증해본건 아니므로, 버그가 있거나 컴파일 자체가 안될 수도 있으므로 주의. -_-;; (디버깅은 알아서 하시라;)
- 2009/06/23DbProviderFactories를 쓸 때, DLL도 잘 있는데 에... [0]
- 2009/04/15콘솔에서 .NET CF 빌드하는 방법 [0]
- 2009/04/02VC에서 _MSC_VER를 이용해 컴파일러에 따른 특성을... [0]
- 2009/04/01.NET에서 제공하는 Code Page 목록 [0]
- 2009/03/24C# 사용자 정의 형식 변환 연산자 [0]

