벌써 2달이 가까이 되어서야 만남기를 쓰게되다니 나의 게으름에 치가 떨린다.
뭐 그때도 별다른 이유가 있어서 만난거는 아니고..
규하형에게 연락해서 만나는데 근처에 올수 있는 선배들에게 연락을 했더니
현수형이 올수 있게되어 같이 만났다.
만남은 합정역에서
1차는 보쌈
2차는 현수형과 둘이서 맥주+육포
1차가 끝나고 규하형은 거래처 회식이 있다고 먼저 가고 현수형과 둘이서 2차를 했지
현수형은 여전히 독설과 자신감으로 가득차있고
나에게 이런저런 조언을 해주었고(특히 지분 관련... ㅡ.ㅡ+++)
즐거운 시간이었다.
'All topics'에 해당되는 글 229건
- 2008.05.07 [2008.03.20]현수형, 규하형 만남
- 2008.05.06 예외를 사용한 코드 다이어트 [warning C4535]
- 2008.05.06 VS2005_sp1 warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다.
- 2008.05.06 warning C4996: was declared deprecated
- 2008.05.06 [진중권 칼럼]온 국민을 희생시킨 이명박 '등신외교' 2
출처 : 마이크로소프트
앞으로 몇 회에 걸쳐 C++의 중요한 기능들을 하나씩 살펴볼 생각이다. 실제로는 별로 쓰이지 않으면서 지식욕을 채우는 데만 도움이 되는 내용보다는 실무에 도움이 되고 일반적으로 받아들여지고 있는 내용을 중심으로 엮어갈 계획이다. 이번 주제는 필자가 평소에 전하고 싶어했던 ‘예외’로 결정했지만, 앞으로의 주제들은 최대한 독자 여러분의 의견을 반영하고 싶다. [출처] 예외를 사용한 코드 다이어트|작성자 캐롤라인
이현창 | 포씨소프트에서 근무하는 필자는 화상 통신 및 e-러닝 관련 소프트웨어를 제작하고 있다. 2003년에는 3년간의 병역특례 근무를 마치고 아주대학교에서의 마지막 대학 생활을 멋지게 마무리하기 위해 열심히 준비중이다.
C++를 만든 Stroustrup은 그의 저서 ‘The Design and Evolution of C++’에서 예외는 반환 값을 대체하기 위한 것이 아니라 결함을 허용하는(fault-tolerance) 시스템을 만들 수 있도록 하기 위한 것이라고 말했다. 에러가 발생한 경우에도 올바르게 동작할 수 있는 프로그램을 만드는 것은 중요한 주제이며 예외는 그러한 일에 적당한 도구이다. 하지만 예외는 기존의 반환 값을 사용한 에러 처리를 훌륭하게 대체할 수 있는 도구이기도 하다.
우선 예외를 사용하지 않은 코드를 한 번 보자. 그리고는 이 코드에서 예외를 사용하도록 고쳐보자. 다이어트 광고에 나오는 두 장의 사진처럼 명백한 차이점을 볼 수 있도록 말이다. <리스트 1>에서는 반환 값을 사용해 에러 처리를 하고 있다. 이러한 방식은 몇 가지 문제점을 가지고 있는데, 먼저 예외를 사용하도록 고친 다음 <리스트 2>와 비교해 보는 것이 좋을 것 같다.
<리스트 2>를 보면 작업 코드는 try 블럭에 모였고 에러 처리 코드는 catch 블럭에 모였다. try 블럭을 보면 이 함수에서 하는 일이 무엇인지 쉽게 알아볼 수 있다. 반면에 <리스트 1>은 예외 처리 코드와 작업 코드가 섞여 있어 함수를 읽기 어렵게 만들고 있다. 그 다음으로 <리스트 2>에서는 여러 군데 중복되어 흩어져 있던 에러 처리 코드들이 하나로 통합됐다. 그렇기 때문에 Log()를 호출하는 대신 다른 일을 하고자 할 때도 수정 작업이 쉽게 이뤄질 것이다. 반면에 <리스트 1>에서는 여러 군데 흩어져 있는 에러 처리 코드를 일일이 수정해야 한다. 소프트웨어 개발에 있어 중복은 개발자가 언제나 피해야 할 것 중에 하나다.
작업 효율에 대해서도 한 번 생각해 보자. <리스트 1>처럼 무슨 일을 할 때마다 비교문을 둬 성공여부를 체크하는 것은 개발자에게 있어서 매우 피곤한 일이며 에러 처리 코드를 작성하는 데 많은 시간을 빼앗기도록 만든다. 예외를 올바르게 사용하면 개발자의 시간이 더 창조적인 일에 사용될 수 있을 것이다.
사실 <리스트 2>처럼 단순히 로그를 찍기 위해 예외를 잡는 것은 납득할 만한 설계가 아니다. 상위의 함수에서 예외 처리할 수 있는 경우에는 굳이 예외를 잡을 필요가 없다. 그런 경우에는 말 그대로 그냥 잡지 않으면 된다. 다음은 예외가 그냥 지나쳐 가도록 변경한 예제 코드다.
// sUserInfo 문자열을 분석해 USER_INFO 구조체를 채우는 함수
bool UserList::ParseUserInfo(MyString sUserInfo, USER_INFO& ui)
{
// ? 문자열 분석기를 구한다.
MyParser& parser = MyParser::GetParser(sUserInfo);
// ? 사용자 ID를 얻는다.
parser.Find ( “ID”, ui.userID );
// ? 사용자 이름을 얻는다.
parser.Find ( “Name”, ui.name );
// ? 사용자 나이를 얻는다.
parser.Find ( “Age”, ui.age );
}
<리스트 1>과 비교했을 때 명백한 차이점을 볼 수 있다. 보다 간결하고, 이해하기 쉽고, 유지 보수하기 쉬운 함수가 됐다. 앞의 코드는 기사에 맞게 작성된 것이긴 하지만 꾸며낸 상황은 아니다. 대부분의 함수에서는 예외를 던지거나 잡을 일이 없다(그리고 이것은 정말 중요한 특징이다). 에러가 발생한 곳에서는 예외를 던지면 되고, 예외가 필요한 곳에서만 예외를 받으면 된다.
언제 예외를 처리해야 하는지 잘 이해되지 않는다면 다음의 가이드라인이 도움이 될 것이다. 다음은 어떤 함수에서 예외를 처리해야 하는 지에 대한 간단한 가이드라인이다.
◆ 함수가 예외를 가지고 무엇을 해야 할 지 아는 경우
◆ 함수가 예외를 적당히 처리할 수 있고, 상위 함수가 예외를 가지고 무엇을 해야 할 지 모르는 경우
◆ 예외를 던지는 것이 프로그램을 비정상 종료시킬 가능성이 있는 경우
◆ 함수가 자신의 일을 계속 진행시킬 수 있는 경우
◆ 리소스를 해제할 필요가 있는 경우
결국은 논리적으로 생각해 알맞게 하는 것이 정답일 것이다. 프로그램 전체적인 관점에서 고려한다면 다음과 같은 가이드라인이 도움이 될 것이다.
◆ 보통의 저수준 함수에서는 예상할 수 있는 예외만을 처리한다.
◆ 그 밖의 예외는 고수준 함수에서 처리한다.
◆ 정말 중요한 저수준 함수에서는 예상할 수 없는 예외도 처리한다. 그리고 적당한 예외를 사용해 외부에 다시 던져준다.
앞서 저수준 함수란 엔진이나 라이브러리 같이 낮은 계층에 속하는 함수에 해당하고, 고수준 함수란 라이브러리를 사용하는 높은 계층의 함수에 해당한다.
예외에 안전하게 설계하기
다음은 예외로 인해 리소스의 유실이 발생할 수 있는 경우에 대한 예제이며 아주 흔한 것이다.
void Func()
{
// 객체의 생성
MyObj* obj = new MyObj();
// 메모리 블럭을 가지고 무엇인가 한다. 실패한 경우 예외를 발생시킨다.
MayThrowException(obj);
// 메모리 해제
delete obj;
}
만약 MayThrowException() 함수에서 예외가 발생하게 된다면 앞서 obj에 할당된 메모리가 해제될 기회를 놓치게 될 것이다. 실제로 프로그램 전반적으로 예외를 사용하고 있다면 이런 상황에 놓일 가능성이 크다. 이런 상황에 대한 일반적인 해결책은 스택을 이용하는 것이다. 다음은 리소스 유실을 막기 위해 클래스를 도입한 예제 코드다.
// 리소스 유실을 막기 위한 클래스
class AvoidLeak
{
public:
AvoidLeak(MyObj* p) : _p(p) {} // 포인터 보관
~AvoidLeak() {delete _p;} // 보관된 포인터 해제
private:
MyObj* _p;
};
void Func()
{
// 객체의 생성
MyObj* obj = new MyObj();
// 리소스 유실 방지용 객체 생성
AvoidLeak al(obj);
// 메모리 블럭을 가지고 무엇인가 한다. 실패한 경우 예외를 발생시킨다.
MayThrowException(obj);
// 메모리를 수동으로 해제할 필요가 없다
}
AvoidLeak 클래스의 소멸자에서는 보관된 포인터를 해제한다. 함수가 정상적으로 종료하는 경우나 예외가 발생해 종료하는 경우 모두 지역 변수의 소멸자는 반드시 호출되도록 정해져 있다. 그렇기 때문에 MayThrowException() 함수에서 예외가 발생하는 경우라도 AvoidLeak 클래스의 소멸자는 올바르게 호출되고 메모리 블럭도 올바르게 해제된다.
예외를 사용해 에러 처리를 한다면 예외에 안전하도록 설계하는 데 신경써야 한다. 간단하게는 <리스트 3>처럼 예외가 발생하는 경우라도 리소스 유실이 일어나지 않도록 설계해야 한다. 더 나아가 예외가 발생하는 경우라도 객체가 올바른 상태를 유지할 수 있도록 설계하는 것이 중요하다. 예를 들어 A라는 작업이 실제로는 a1 - a2 - a3라는 작업으로 이뤄진다고 가정해 보자. 작업 a2가 수행되는 과정에서 에러가 발생했다면 a1의 작업은 올바르게 복구(rollback)될 수 있도록 설계돼야 한다.
<리스트 3>은 내부적으로 필요한 리소스를 초기화하는 함수다. 이 함수에서는 예외가 발생할 수 있는 곳이 여러 군데 있는데, new 연산자에서 메모리 할당을 실패하는 경우에도 예외가 발생할 수 있고 Commit() 내에서 실패하는 경우에도 예외가 발생할 수 있다.
만약에 이 함수가 실행되고 리소스 ?번을 초기화하는 과정에서 예외가 발생한다면 어떻게 될까? LargeObject 객체는 일부만 초기화되어 있는 올바르지 않은 상태가 될 것이고 이는 여러 경우에 문제를 발생시킬 것이다. <리스트 4>는 이러한 문제에 대한 일반적인 해결책이다.
auto_ptr은 <리스트 4>에 나오는 AvoidLeak과 같은 클래스로서 예외가 발생하는 경우에도 리소스가 올바르게 해제될 수 있도록 하는 역할을 한다(auto_ptr에 대한 자세한 설명은 박스 기사에서 볼 수 있다). 그리고 MyResource를 LargeObject 객체의 멤버 변수에 보관하는 대신 지역 변수에 보관했기 때문에 예외가 발생하는 경우라도 LargeObject 객체의 내부 상태는 올바르게 유지된다. 모든 작업이 성공적으로 완료된 후에야 LargeObject 객체의 내부 상태가 변경된다. 이러한 패턴을 다음과 같이 요약해 볼 수 있다.
짾 예외가 발생할 만한 작업은 지역 변수를 사용해 진행한다.
짿 안전한 방법만을 사용해 클래스의 내부 상태를 변경한다.
예외에 관한 이런 저런 이야기
생성자에서 예외 발생
모두가 알고 있듯 생성자는 반환 값을 가지고 있지 않다. 그렇기 때문에 생성자에서 발생한 에러를 알리기 위해 예외를 사용하는 것은 아주 좋은 생각이다. 그러나 그것이 의도적이든 의도적이지 않든 간에 생성자에서 예외가 발생하는 경우에는 다음과 같은 몇 가지 규칙을 알아둬야 한다.
짾 생성자에서 예외가 발생한 경우 객체는 생성되지 않는다 : 객체의 생존 기간은 생성자의 끝(닫는 괄호)에서부터 소멸자의 시작(여는 괄호)까지이다. 생성자에서 예외가 발생한 경우에는 생성자의 끝에 도달하지 못한 것이고 결국 생성되지 못한 것이 된다. 그렇기 때문에 객체의 소멸자는 호출되지 않는다. 소멸자가 호출되지 않기 때문에 생성자에서 할당한 리소스가 올바르게 제거되지 않을 수 있다는 점을 기억해야 한다. 생성자에서 예외가 발생할 가능성이 있는 경우에는 catch문을 두어 리소스를 깨끗이 정리하고 다시 예외를 던져야 한다.
짿 생성자에서 예외가 발생한 경우 이미 생성된 멤버들은 어떻게 처리될까 : 생성자에서 예외가 발생한 경우 어떤 멤버는 이미 생성되었고, 어떤 멤버는 아직 생성되지 않았을 수 있다. 예를 들어 이미 생성된 멤버가 메모리를 할당받았다면 이 메모리는 어떻게 해제할 수 있을까? 다행히도 우리가 신경써줘야 하는 부분은 없다. 이미 생성된 멤버의 경우에는 올바르게 소멸자가 호출되는 것을 확인해 볼 수 있다(<리스트 5>).
Member 클래스는 두 번째 멤버 객체를 생성할 때 생성자에서 예외를 던지도록 제작된 클래스다. 그렇기 때문에 Container 클래스의 생성자에서 두 번째 멤버 객체인 m2를 생성할 때 예외가 발생될 것이다. <리스트 5>의 결과에서 볼 수 있듯 완전하게 생성된 m1은 올바르게 소멸자가 호출됐다. m2는 자신의 생성자에서 예외가 발생했기 때문에 생성되지 못했다. m3는 생성자조차 호출되지 못했다.
new[] 연산자를 사용해 객체의 배열을 생성하는 경우에도 같은 원칙이 적용된다. 객체의 배열을 생성하는 도중에 예외가 발생한다면 이미 생성된 객체가 있을 수 있고, 아직 생성되지 않은 객체가 있을 수 있다. 이 경우에도 이미 생성된 객체에 대해서는 소멸자가 올바르게 호출되는 것을 확인할 수 있다.
쨁 생성자의 초기화 리스트에서 발생하는 예외는 어떻게 잡을까 : 생성자의 초기화 리스트에서는 부모 클래스의 생성자나 멤버 생성자를 직접 호출할 수 있으며 생성자의 본문 밖에 위치한다. 초기화 리스트에서 예외가 발생하는 경우에는 어떻게 잡을 수 있을까? <리스트 6>은 생성자의 초기화 리스트에서 발생하는 예외를 잡는 방법을 보여준다.
필자에게도 그다지 익숙하지 않은 문법이지만 초기화 리스트에서 발생하는 예외를 잡을 필요가 있을 때는 유용하게 사용할 수 있을 것이다. 한 가지 아쉬운 것은 비주얼 C++ 6.0에서는 이와 같은 문법을 지원하지 않는다는 점이다. 그러나 다음 버전인 비주얼 C++.NET에서는 사용 가능하다.
소멸자에서 예외 발생
스택을 정리하는 과정에서 예외가 발생하면 응용 프로그램이 비정상적으로 종료될 수 있기 때문에 소멸자에서는 절대로 예외가 발생해서는 안 된다. 소멸자에서 예외를 발생시킬 수 있는 함수를 호출하는 경우에는 반드시 catch로 잡아주도록 하자. 또한 delete나 delete[]를 오버로드한 경우 역시 절대로 예외가 발생하지 않도록 주의해 제작해야 한다.
Win32 구조적 예외 처리
Win32 구조적 예외 처리(Structured Exception Handling, 이하 SEH)는 윈도우 운영체제 수준에서 구현되어 있는 예외 처리 기능이다. 여기서의 예외는 C++의 예외와는 다른 것이며, 잘못된 메모리 참조나 스택 오버플로우와 같은 시스템 수준의 예외를 말한다. 우선 SEH를 사용해 잘못된 메모리 참조 예외를 잡는 방법을 살펴보자.
void Func()
{
__try
{
// 잘못된 주소 참조 오류를 발생시킨다.
char* p = NULL;
*p = ‘A’;
}
__except ( EXCEPTION_ACCESS_VIOLATION == GetExceptionCode()
? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH )
{
// Access violation
}
}
SEH는 C++의 try, catch와는 달리 __try, __except 키워드를 사용한다. GetExceptionCode()는 예외의 종류를 알려주는 함수이고, 이 예제에서는 잘못된 메모리 참조인지 비교하고 있다. 잘못된 메모리 참조인 경우에는 EXCEPTION_EXCUTE_HANDLER 값을 반환함으로써 __except 블럭이 실행되도록 하고, 잘못된 메모리 참조가 아닌 경우에는 EXCEPTION_CONTINUE_SEARCH 값을 반환해 다른 __except 블럭을 찾아보도록 하고 있다.
SEH는 시스템에서 발생하는 예외를 잡을 수 있을 만큼 강력하지만, C++ 객체가 선언된 함수에서는 함께 사용할 수 없다(좀더 자세히 말해 함수 종료시 호출돼야 할 소멸자가 있는 함수를 말한다). 다행히도 SEH 예외를 C++ 예외처럼 다룰 수 있는 방법이 있는데, 이 방법을 사용하면 같은 함수 안에서도 SEH와 C++ 예외를 함께 사용할 수 있을 뿐더러 일관된 예외 처리 방식을 사용할 수 있어서 좋다. 다음은 SEH 예외를 C++ 예외로 만든 예제다.
#include “stdafx.h”
#include
#include
// SEH 예외는 이 예외 클래스로 던져진다.
class CSEHException
{
public:
CSEHException(UINT excode, PEXCEPTION_POINTERS exp)
{
// SEH 예외와 관련된 코드를 저장한다.
m_exceptionCode = excode;
m_exceptionPointer = *exp;
}
int GetExceptionCode() {return m_exceptionCode;}
UINT m_exceptionCode; // 예외 코드
EXCEPTION_POINTERS m_exceptionPointer; // 부가 정보
};
// SEH를 C++ 예외로 변경하기 위한 함수(시스템에 의해 호출된다)
void _cdecl SEH2CppException(UINT excode, PEXCEPTION_POINTERS exp)
{
throw CSEHException(excode, exp);
}
void main()
{
// SEH 변경 함수를 등록한다.
_set_se_translator(&SEH2CppException);
try
{
// 잘못된 주소 참조 예외를 발생시킨다.
int* i = NULL;
*i = 123;
}
catch( CSEHException& e)
{
switch(e.GetExceptionCode() )
{
case EXCEPTION_ACCESS_VIOLATION:
// 여기가 실행된다.
break;
}
}
}
SEH 예외를 C++ 예외로 만드는 방법은 아주 간단하다. 시스템은 SEH 예외가 발생할 때마다 정해진 함수를 호출하도록 되어 있는데, _set_se_translator()를 사용하면 우리가 작성한 함수를 호출하도록 만들 수 있다. 그리고 우리가 작성한 함수 안에서는 C++ 예외를 던지면 된다.
앞 예제에서는 SEH 에외가 발생한 경우 SEH2CppException()을 호출하도록 지정했으며, SEH2CppException() 안에서는 CSEHException 객체를 예외로 던지는 것을 확인할 수 있다. 또한, main() 함수를 보면 잘못된 메모리 참조 예외가 CSEHException로 던져지는 것을 확인할 수 있다. CSEHException을 사용하는 것이 얼마나 편리한지 보여주기 위해 이 기능을 사용하지 않은 경우와 사용하는 경우를 비교해 보았다(<리스트 7, 8>).
누가 보아도 <리스트 8>의 경우가 훨씬 이해하기 쉽다. 게다가 더욱 안전하다. 포인터가 NULL이 아닌 경우라도 얼마든지 잘못된 주소를 가리키고 있을 수 있다는 사실을 명심하자! 이런 경우에 <리스트 7>은 심각한 문제를 일으키게 되지만 <리스트 8>은 안전하게 예외를 잡아낼 수 있다. 그렇다고 해서 <리스트 8>이 성능 상의 문제를 가지고 있는 것은 아니다. 예외가 빈번히 일어나는 것이 아니라는 가정에서 <리스트 8>은 비슷하거나 더 빠르게 수행된다.
기사에 대한 많은 조언을 당부하며
이번 호에는 많은 전문가들을 통해 밝혀지고 알려진 올바른 예외 사용법에 대해 알아봤다. 안타깝게도 지면이 부족한 관계로 몇 가지 중요한 정보를 전달하지 못했는데, 다음과 같은 것들이다. 이런 부분은 참고 서적을 통해 충분한 지식을 습득할 수 있을 것이라고 생각한다.
◆ new 연산자에서 할당에 실패한 경우의 올바른 처리 방법
◆ 프로젝트에 사용할 기반 예외 클래스를 작성하는 방법
◆ 예외에 안전한 클래스를 작성하는 방법에 대한 보다 깊은 지식
이번 기사를 작성하면서 가장 어려운 부분은 어떤 내용이 실무 개발자들에게 도움이 될지에 대한 정보가 부족했다는 점이다. 이번 기사에 대한 질책이나 다음 호에 대한 조언, 희망 사항을 들을 수 있다면 좀더 좋은 기사를 쓰는 데 도움이 될 것이다.
[ auto_ptr 클래스 ]
AvoidLeak은 MyObj*에 대해서만 사용할 수 있지만, 템플릿을 사용하면 쉽게 여러 가지 타입을 담을 수 있는 클래스로 만들 수 있다. 실제로 C++ 표준 라이브러리에는 auto_ptr 클래스가 이러한 용도로 제공된다.
하지만 auto_ptr은 배열에 대해 사용할 수 없으며, 소유권 이전 방식의 복사 기능을 제공하기 때문에 STL 컨테이너에 보관할 수 없다. http://boost.org에서는 이러한 문제점을 해결한 scoped_array이나 shared_ptr과 같은 클래스를 제공한다. 자세한 정보는 해당 사이트에서 얻을 수 있다.
[ 컴파일 옵션의 사용 ]
<리스트 8>을 컴파일하기 위해서는 컴파일 옵션으로 /EHa를 주어야 한다. 그렇지 않은 경우 비주얼 C++.NET에서는 다음과 같은 경고 메시지를 출력한다.
warning C4535: calling _set_se_translator() requires /EHa
the command line options /EHc and /GX are insufficient
다음은 예외와 관련된 컴파일 옵션이다.
/EHa 비동기 모드
/EHs 동기 모드
/GX (/EHsc) 동기 모드. 끝에 붙은 c는 extern “C” 함수는 예외를 발생시키지 않음을 의미
비동기 모드는 함수 또는 함수에서 호출하는 자식 함수에 throw문이 없어도 예외가 발생할 수 있다고 가정한다. SEH 예외는 throw문이 없어도 언제든지 발생할 수 있기 때문에 비동기 모드로 컴파일해야 한다.
VS2005_sp1 warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다.
knowhow/Visual C++ 2008. 5. 6. 18:48사례1)
warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss
닷넷에서 한글로 주석을 달면 나올 수 있는 워닝이라고 한다...
그래서인지 구글에서 검색해보면 이 워닝으로 귀찮아하는 외국인을 찾을 수 없다ㅎㅎ
#pragma warning(disable:4819) 로 무시해주거나~
주석을 영어로 달면 해결될듯?? <- 이방법은 안해봤으나 앞으로는 이렇게 해야겠다고 맘먹는중??ㅎㅎ
사례2)
warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오
d3d9types.h 에 보면..
1801번째 줄에서 볼수 있는 구조체 이다.
( Ctrl + G 를 누르면 한방에 갈 수 있다는 것은 알고 있죠?! 마우스 휠 비비지 말자.. 남들 보면 오해한다.. -0-? 뭘?! )
typedef struct _D3DDEVINFO_VCACHE {
DWORD Pattern; /* bit pattern, return value must be FOUR_CC(멌? 멇? 멌? 멖? */
DWORD OptMethod; /* optimization method 0 means longest strips, 1 means vertex cache based */
DWORD CacheSize; /* cache size to optimize for (only required if type is 1) */
DWORD MagicNumber; /* used to determine when to restart strips (only required if type is 1)*/
} D3DDEVINFO_VCACHE, *LPD3DDEVINFO_VCACHE;
주석문중에 깨진 글자가 보일 것이다.
과감히 지워주자... 이제 더이상의 찜찜한 기분은 느낄 필요가 없다..
VS.NET 2003 혹은 2005로 컴파일을 하다보면
warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오.
이런 형태의 warning 메세지를 확인할 수 있습니다. warning 이기는 하지만 그래서 상당히 눈에 거슬리는 부분이 아닐 수 없습니다.
그래서 이번에 그 원인과 해결방법을 알아 보고자 합니다.
[원인]
ANSI로 인코딩된 소스코드를 VS.NET 2005 (한글판)에서 빌드하면서 발생하는 문제로 일본판의 경우에도 비슷한 문제가 발생하였고 영문판 VS.NET 2005에서는 발생하지 않는 것으로 알려졌습니다.
MS에서도 이를 버그로 인정하고 다음 버전에서 수정한다고 합니다.
[해결방안1]
#pragma warning(disable: 4819)
이 문장을 상단에 위치시켜서 해당 warning이 표시되지 않게 한다.
[해결방안2]
VS.NET 2005의 경우
'프로젝트->속성->구성속성->C/C++->고급->특정 경고 사용 안함'
항목에 4819와 같이 무시하고 싶은 경고 메세지 번호를 넣는다.
[해결방안3]
세번째로는 warning이 발생하는 파일을 새롭게 유니코드 형태로 저장하는 방법입니다.
VS.NET 2005의 경우
'파일->저장 고급 옵션'
"유니코드 - 코드페이지 1200" 형태로 저장을 선택하시면 됩니다.
메모장 등 기타 편집기를 이용하셔도 됩니다.
현재 전반적으로 사용하는 방법이 위에 3가지 정도 인듯 합니다.
저의 경우 이 warning이 DXSDK에서 발생해서 당황했었던... ^^
처음엔 #pragma 형태로 했었는데 해결방안2 형태로 하니까 편하더군요.. ^^
비쥬얼 스튜디오 2005에서 컴파일 하다 보면 위의 warning이 뜨는것을 볼 수 있다.
몇가지 경우가 있는듯 한데
대표적으로 예전의 문자열 관련 CRT 함수를 쓰면 나타난다.
위 warning의 의미는 "VS2005에서 이전 문자열 관련 CRT함수의 안전성을 강화하기 위하여
"_s"가 붙는 함수를 다시 만들었기 때문에 될 수 있으면 이전에 사용하던 함수는 사용하지 마라" 정도가 되겠다.
예) strcpy -> strcpy_s
안전성이라고 해봐야 특별한것은 없고 메모리 관련 에러가 나면 확실하게 에러를 표시해 주는 기능 정도인거 같다 (이전 함수들은 메모리 버퍼의 크기에 대한 보장을 못함). 그래도 메모리 관련 에러가 나면 그 결과가 엉뚱한 데서 나타날 수가 있으므로 여간 찾기 어려운 것이 아닌데 이런 사소한것 부터 조심스럽게 쓰면 좀 더 안전하게 코딩할 수 있지 않을까 생각이 든다.
그래서 요즘 드는 생각들이 C 함수 보다는 C++이 제공해주는 (엄밀하게 말한다면
C++ 로 만든 표준 라이브러리)클래스를 보다 폭넓게 사용하는것이 좋겠다라는 생각이 든다.
STL에서 제공해주는 스트링 클래스나 여러 컨테이너를 사용한다면 직접 문자열을 다룬다거나
new delete를 사용하는 빈도가 줄어들터이니...
java가 부러운점이 있다면
필요로하는 거의모든 라이브러리를 표준차원에서 제공해준다는것이다.
C++ 같은경우 간단한 문법(사실 문법자체도 어렵거니와)과 STL을 뺀다면
표준이랄께 없기 때문이다.
투정이 좀 길었는데
처음으로 돌아가서
만약 이전에 짜놓았던 코드를 고치기 힘들면 복잡하게 생각할꺼 없고
stdafx.h 파일의 최 상단에
#define _CRT_SECURE_NO_DEPRECATE
한줄 넣어버리면 그만이다...
[출처] warning C4996: was declared deprecated |작성자 바둑이
정권은 광우병의 공포 앞에서 대중이 패닉에 빠졌다고 본다. 하지만 촛불 시위 현장은 공포에 질려 절규하는 게 아니라, 즐겁게 야유하는 축제의 분위기다. 정권은 시위의 배후에 정치 세력의 선동이 존재한다고 본다. 하지만 정치 세력들은 어리둥절한 채 대중이 주도하는 민란(?)에 뒤따라가기 바쁘다. 정권은 국민을 계몽해야 한다고 생각한다. 하지만 대중의 분노가 광우병 홍보로 수그러들 것 같지는 않다. 그것은 좀 더 깊은 근원을 갖고 있기 때문이다. 미국에서도 우매한 한국인의 계몽에 나섰다. 미국 농림부의 입장은 단호하다. "이 자리는 식품 문제만을 논의하기 위한 자리이지 협상 문제를 논의하기 위해 이곳에 온 것이 아니다." "광우병 문제가 발생한다고 하더라고 쇠고기 공급의 안전을 보장할 수 있는 핵심은 광우병 특정 위험 물질(SRM)을 제거하는 것이기 때문에 미국산 쇠고기를 즉각적으로 중단求?것을 원치 않는다." 한 마디로 '즐쳐셈', 자신들이 멍청한 상대에게 쉽게 관철시켰던 그 입장의 반복이다. 광우병은 확률의 문제? 정권이 위기에 빠지자 조·중·동이 나섰다. 그들은 애써 논점을 일탈시키려 한다. 그 방법은 광우병에 관한 담론을 광우병의 발병 확률에 관한 문제로 환원시키는 것이다. 하긴, 순수 확률로 따지면, 광우병이 대량으로 발생했던 영국에서조차 그 확률은 접시 10억 개 중의 한 명 꼴도 안 된다고 들었다. 심지어 "광우병에 걸린 소의 고기를 먹은 사람이 광우병에 걸릴 확률은 골프장에서 골프를 치다가 벼락 맞아 죽을 확률보다 훨씬 낮다." (<연합뉴스> 2007/8/27일) 그 말이 맞는다고 하자. 조·중·동의 논설위원들, 청와대와 내각, 한나라당 의원들 모두 골프 치러 다니시는 것으로 안다. 이 분들께 특별히 광우병에 걸린 소의 고기를 수입해 메뉴로 제공하는 게 어떨까? 척수로 감자탕, 소장으로 곱창 만들어 드리는 거다. 벼락 맞을 걱정 없이 스윙 하시는 분들이니, 안심하고 드실 게다. 국민을 계몽시키려면, 여러 말 할 것 없이 직접 광우병 쇠고기를 시식하면 된다. 그래야 무지몽매한 국민들이 공포(?)에서 벗어나 '아, 따라 먹어도 되겠구나' 생각할 게 아닌가. 수입된 미국 쇠고기 중에서 단 한 상자라도 광우병에 걸린 소가 도축된 것으로 드러날 경우, 아마도 사회에는 커다란 패닉이 일어날 것이다. 이것을 단지 '광우병 발병 확률이 극히 낮다'는 사실을 모르는 대중의 무지가 일으킨 해프닝이라 설명할 수 있을까? 게다가 그 경우 수입 쇠고기는 물론이고 애먼 국산 한우까지도 소비가 급감할 것이다. 그때에도 '원산지 표시를 확실히 한 이상 한우는 안전하다'는 말로써 대중의 무지를 탓할 것인가? 그게 이런 문제다. 광우병이 발생한 나라로부터 쇠고기의 수입을 당장 중단하는 것이 광우병 발병 확률이 낮다는 사실을 모르는 무지의 소치일까? 그렇다면 왜 한국은 미국에서 광우병이 발발하자마자 즉각 수입을 중단시켰던가? 왜 일본은 아직까지 20개월 미만의 소의 수입만을 허용하는 것일까? 그리고 미국에서 쇠고기를 수입하는 여러 나라들이 미국과의 협상에서 그렇게 끈질기게 검역 조건을 강화하려고 하는 것일까? 이 모두가 과학적 무지에서 비롯된 불필요한 정치적 제스처는 아닐 것이다. 원희룡 의원의 말대로 이건 "확률의 문제가 아니다." 아무리 발병 확률이 낮아도, 광우병은 단 한 건만 발생해도 커다란 사회적 패닉이 일어나고, 한 나라의 축산업의 기반이 흔들리기 때문이다. 그러니 광우병의 낮은 확률에 관한 얘기는 청와대와 조중동에서나 열심히 떠들게 내버려두고, 우리는 이번 탄핵 사태의 본질적인 문제로 넘어 가기로 하자. 제가 한 말도 잊어버리는 저 편리한 건망증 환자들에게는 그들이 과거에 자기 신문에 실었던 사설을 들이대면 그만이다. 그들의 기억을 되살려 주자. 광우병 괴담의 출처는 조·중·동 조·중·동이 제 지면에 실은 것 중에 광우병의 위험을 강조하는 그 모든 기사들은 생략하기로 하고, 그냥 사설만 몇 개 보자. 먼저 <조선일보>의 사설이다. 지금 읽어 봐도 명문이다. <조선일보>는 "광우병 파동의 파괴적 요소는 불확실성과 일반적 무지에 있다"고 정확히 짚으며, "국민 보건에 대한 장기적 안전보장의 측면에서 신중하고 완벽하게 대책"을 만들어야 한다고 주장하며, 그렇지 않을 경우 "그 후환은 자손들에까지 이어질 것"이라 경고하고 있다. [사설] 광우병, 제대로 알려야 (2001/02/07) 광우병 우려가 국내서도 급속히 확산되면서 축산농가와 사료업계는 물론, 유통업과 서비스산업 등에도 광범위한 파장을 유발하고 있고 소비자도 혼돈에 빠져들고 있다. (...) 이 문제는 단순히 농정이나 경제의 문제가 아니다. 국민보건에 대한 장기적 안전보장의 측면에서 신중하고 완벽하게 대책을 만들어내야 한다. 눈앞의 난관이나 관료주의적 책임회피 때문에 임기응변이나 호도책으로 이 문제를 잘못 다루면 그 후환은 자손들에까지 이어질 것이다. 광우병 사태의 정면대응을 위해서는 무엇보다도 모든 관련자료와 사실들이 가감 없이 진실대로 밝혀져야 한다. 광우병파동의 파괴적 요소는 불확실성과 일반적 무지에 있다. 광우병으로 불리는 소의 BSE병이나 그와 유사한 증세를 나타내는 인간의 변형 크로이츠펠트야코브(vCJD)병에 관해서는 아직도 그 병원체의 전모나 발병기전, 감염경로, 양자간의 상관관계 등의 여러 중요한 요소들이 확연히 밝혀지지 않아 현재로서는 예방적 조치와 정확한 정보의 보급이 매우 중요하다. 이 점에서 보면 정부의 그간의 태도는 납득하기 어렵다. 지난 10여년 동안 세계가 광우병 파동으로 영일이 없는 동안 정부는 줄곧 우리는 안전하다고 장담만 해왔다. 다른 나라들은 진작 수입을 금지한 소 추출물이나 골분수입 사실도 외국언론이 폭로할 때까지 계속 침묵했으며, 문제가 되고 있는 동물성 사료나 음식물 찌꺼기 사료도 수년간 국내에서 사용되었고, 일부는 이미 도축, 유통되었는데도 계속 문제없다고 주장해 왔다. 물론, 음식찌꺼기 사료화는 자원절약의 고육지계였음을 충분히 이해할 수 있지만 당시 많은 전문가들이 그의 위험성을 제기했는데도 정부는 듣지 않았다. 지금이라도 늦지 않았다. 정부는 다른 어떤 측면보다도 국민건강을 우선해 철저한 예방적 조치를 강화하고 모든 관련 정보와 사실을 국민들에게 정확히 전달해야한다. 불필요하게 공포가 확산되어서도 안 되지만 무지와 무사안일로 인해 화를 자초하는 어리석음은 절대 없어야 한다. 다음은 <동아일보>의 사설이다. <동아일보>는 "광우병의 원인과 방지책은 아직 미확인 상태라 방심할 수 없다"며, 심지어 "사슴광우병에 걸린 것으로 추정되는 사슴의 캐나다산 녹용"까지 걱정한다. 정부에서 동물성 사료 실험을 한 것을 두고는 "국민도 시험대상"으로 삼았다고 질타하며, "광우병 제로 국가라고 선언할 수 있도록" "0.1%의 가능성도 없애는 노력"을 해야 하며 "소의 전수조사"까지 권한다. 미국에서 광우병으로 의심되는 소가 발견됐을 때에는, "정부가 최우선순위를 둬야할 가치는 국민의 생명과 건강"이라며, "위해(危害)를 없애는 데 필요한 경제적 손실은 감수할 수밖에 없다"고 주장했다. 그 소가 광우병으로 확인도 되기 전에 정부에서 수입중단을 하고 척추 뼈와 내장의 판매를 중단시켰지만, "그렇다고 해서 안심하기에는 이르다"고 말한다. [사설]광우병과 홍역, 느슨한 대책 (2001/01/28) 광우병 파동은 1992년 영국에서 시작돼 1996년부터는 유럽에서 수많은 소의 강제 도살, 쇠고기 판매 중지와 금수 조치로 이어졌다. 지난해 독일에서는 이에 대한 대처를 소홀히 한 책임을 지고 주무장관 2명이 사임하기도 했다. (...) 광우병의 원인과 방지책은 아직 미확인 상태라 방심할 수 없다. 더구나 국내에는 사슴 광우병에 걸린 것으로 추정되는 사슴의 캐나다산 녹용도 유통된 것으로 알려지고 있다. 정부 당국은 이웃 일본이 1999년부터 CJD를 법정전염병으로 지정하고, 유럽산 쇠고기 수입을 금지하는 등 적극적으로 대응하고 있음을 직시할 필요가 있다. [사설]광우병 정말 안심해도 되나 (2001/02/05) 더욱 놀라운 것은 광우병의 위험성이 유럽을 들끓게 하던 시점에 정부연구소가 동물성 사료 실험을 했다는 점이다. 그 사료를 먹은 소의 고기와 뼈 등을 유통시켰다면 결과적으로 국민도 시험 대상이 된 셈이 아닌가. (....) 정부가 우리나라에서는 광우병이 발생하지 않았다는 사실만으로 광우병 안전지대라고 강조하는 것은 소극적인 대책일 뿐이다. (...) 정부는 광우병 제로 국가라고 자신 있게 선언할 수 있도록 광우병이 유입될 수 있는 모든 분야를 철저히 점검하고 확인하는 대책을 강구해야 한다. [사설]광우병 안전지대 아니다 (2001/09/11) 정부는 긴급히 일본에서 수입되는 광우병 관련 축산물에 대한 잠정 수입검역조치를 취했지만 이미 수입됐던 축산물에 대해서도 유통 경로를 파악하는 등 철저한 대비책을 세워야 한다. 일본은 업계에서 지나치다는 반응이 나올 정도로 광우병 방지 대책을 시행했는데도 이런 일이 벌어져 충격을 감추지 못하고 있다. (...) 한국은 96년부터 영국 등 광우병 발생국가로부터 소 등 반추동물과 축산물의 수입을 금지했지만 광우병의 잠복기간(3∼5년)이 길어 완전히 마음을 놓기는 어렵다. (...) 한국도 안전지대에 있지 않은 것이 확실해졌으므로 단 0.1% 가능성도 없애는 노력을 기울여야 한다. (...) 정부는 소비자를 안심시키기 위해 소의 전수 검사를 실시해보는 방안을 검토해보기 바란다. [사설]광우병 비상, 식탁 안전 만전 기해야 (2003/12/25) 미국에서 광우병에 걸린 것으로 의심되는 소가 발견돼 전 세계가 긴장하고 있다. 미국산 쇠고기는 국내 쇠고기 시장의 44%를 차지하고 있어 우리 식탁의 안전과도 직결된다. (...) 정부가 최우선순위를 둬야할 가치는 국민의 생명과 건강이다. 위해(危害)를 없애는 데 필요한 경제적 손실은 감수할 수밖에 없다. 정부는 이미 미국산 쇠고기의 통관을 보류시켰고, 광우병 발생 사실이 최종 확인되면 수입을 전면중단할 계획이라고 한다. 또 유통 중인 척추뼈와 내장의 판매를 금지시켰다. 그렇다고 해서 안심하기에는 이르다. 마지막으로 <중앙일보> 사설이다. 중앙일보는 소에게 음식찌꺼기 좀 먹였다고 난리를 치며, 심지어 해외 여행자가 구입한 "유럽산 화장품"에 대한 대책까지 주문한다. 북한이 독일에 광우병 때문에 살 처분한 소를 지원해 달라고 요청했을 때에는, 이를 "문명 국가의 도덕률에 크게 어긋나는 일이며 심하게 말하면 인종 차별"이라고 비판하며, 잠복기가 수십 년에 이르고, 말기 이전에 증세를 감지하기가 거의 불가능하다고까지 말할 만큼 이 병의 위험성은 심각하다"고 주장한다. 나아가 칼럼에서는 실제로 발병 확률이 낮은데도 광우병에 대한 공포가 클 수밖에 없는 이유를 '위험 심리학'으로 상세히 설명하고 있다. [사설] 뒷북치는 광우병 대책 ( 2001/02/06) 광우병 원인으로 지적되는 동물성 사료가 음식물 찌꺼기 사료화 사업 명분으로 국내에서 사용되고 해외에서도 수입된 것으로 밝혀져 국민을 불안케 하고 있다. 농촌진흥청 산하 축산기술연구소의 대관령 지소와 경기도 안성 등지에서 1999년 4월부터 소 3백 마리에 음식물 찌꺼기로 만든 사료를 먹였으며 이 가운데 40마리는 지난해 말 도축돼 시중에 팔렸다고 한다 (...) 정부는 또 97년 7월부터 유럽지역 전체의 소.양 뇌나 척수 등 성분이 포함된 화장품 수입을 금지했다고 강조하고 있다. 하지만 해외여행자 증가 등으로 국내에서도 어렵지 않게 접할 수 있는 게 유럽산 화장품이다. [사설] 광우병 쇠고기 北지원이라니 (2001/02/17) 광우병 공포증이 전세계를 휩쓰는 가운데 광우병 감염 우려로 도살된 쇠고기가 북한에 지원될 것이라는 소식은 충격적이다 (...) 결론부터 말하면 북한은 아무리 기아가 위중하다 하더라도 이런 모멸적인 지원 요청을 즉각 취소해야 한다 (...) 그러한 지원은 문명국가의 도덕률에 크게 어긋나는 일이며 심하게 말하면 인종차별적이라고까지 할 수 있을 정도다. (...) 더욱이 역학자들이 인간의 경우 잠복기가 수십년에 이르고, 말기 이전에 증세를 감지하기가 거의 불가능하다고까지 말할 만큼 이 병의 위험성은 심각하다. (...) 치명적인 변종 크로이츠펠트야콥병(vCJD)을 유발할 가능성이 커 화장품 원료로도 못쓰게 하는 쇠고기를 자기 인민에게 먹이겠다는 발상은 참으로 이해하기 어렵다. [분수대] 위험 심리학 (2001/02/12일) 한국의 광우병 파동을 보자. 소나 사람에서 광우병이 발병한 사례는 없으며 우리 쇠고기는 안전하다고 정부와 전문가가 아무리 홍보해도 쇠고기 소비는 줄어들고 축산농가는 상이다. 광우병에 걸린 소의 부산물을 섭취한 경우에만 위험이 있다고 강조해도 상황은 달라지지 않는다 (...) 이에 대해서는 위험 심리학이 설명하고 있다. 사람들은 자기 스스로 선택한 행동(흡연. 운전. 스키 등)에서 오는 위험은 받아들일 준비가 돼 있다는 것이다. 평생 흡연을 하면 수명이 10년가량 줄어든다. 한국의 교통사고 사망자수는 하루 평균 30여명에 이른다. 스키장에서 골절상을 당하는 경우도 비일비재하다. 이에 대해 사람들은 "나는 예외일 것" 이라고 생각하면서 "그래도 사고가 나면 어쩔 수 없지" 하고 받아들인다는 것이다. (...) 그러나 대중은 선택하지 않은 위험에 대해서는 민감하게 반응한다. '혹시' '만의 하나라도' 고압선이 암을 유발한다거나 쇠고기가 인간 광우병을 일으킬지 모른다는 가능성도 이에 포함되는 것이다. (조현욱 문화부 차장) 근데, 이 많던 광우병 괴담은 그들의 지면에서 다 어디로 사라졌을까? 사전예방의 원칙 한미 쇠고기 협상이 '졸속'이었다는 점에 관해서는, 청와대와 조중동만 빼고, 일반적 합의가 존재한다. 한나라당에서마저 협상의 문제점은 인정하는 모양이다. 그래선지 어제 열린 당정청 긴급회의에서 한나라당은 "협상내용이 주변국들에게 불리할 경우 재협상이 가능하다"는 입장을 밝혔다고 한다. 앞으로 미국과 주변국들의 협상이 어떻게 진행될지는 모르지만, 적어도 현재의 시점에서 한국의 협상내용이 주변국들과 비교해 터무니없이 불리하다는 것은 누구도 부인할 수 없을 것이다. 광우병이 위험하다는 사실은 일반적으로 인정된다. 광우병이 의심되는 쇠고기를 피할 수 있는 방법도 존재한다. 즉 광우병이 우려되는 지역에서는 수입을 안 하면 된다. 하지만 수입을 피할 수 없을 경우에는 최대한 검역조건을 엄격히 해야 한다는 데에도 누구나 동의할 것이다. 그런데 이번 협상의 내용에 따르면, 광우병 위험 부위까지 수입해야 하고, 광우병 발생 시에도 수입을 중단할 수 없다. 한 마디로 자진해서 모든 것을 다 내주고 협상에서 빈손으로 돌아온 것이다. 광우병 감염 확률은 '무시해도 좋을 양'(quantité negligeable)이라고 말하려는가? 그 확률이 골프 치다가 벼락 맞을 것보다 낮다면, 광우병에 걸린 쇠고기를 수입해 자기도 먹고, 자기 아내도 먹고, 자식에게도 먹여 보라. 평소에 벼락 맞을까봐 외출도 못하는 가족이 아니잖은가. 광우병의 위험을 줄일 수 있는 모든 장치들을 다 해제해 놓고, 위험을 과장하지 말라고 말하는 것은 논점의 일탈이다. 분명히 말해두는데, 이것은 예방의학의 차원에서 광우병 위험의 대비책에 관한 논의다. 예방의학을 전공하는 단국대 권호장 교수의 칼럼은 이 문제를 대하는 올바른 태도가 무엇인지 말해준다. 이게 FM이다. 한나라당도, 조중동도, 농림부도 정권이 바뀌기 전에는 이렇게 주장했었다. "현재까지 우리 국민이 미국산 쇠고기를 먹으면 인간광우병에 걸린다는 과학적 증거는 없다. 그러나 이것은 과학적 정보가 부족한 것을 의미하는 것이지, 미국산 쇠고기가 안전하다는 과학적 증거는 결코 아니다. 환경보건 교과서에서는 미국산 쇠고기처럼 안전성에 대한 과학적 증거가 불확실할 때 '사전예방의 원칙'에 입각해서 행동하라고 가르친다. '사전예방의 원칙'의 첫째 원칙은 위험성에 대한 과학적 증거가 불확실하더라도 먼저 조치를 취하라는 것이다. 10년쯤 국민에게 먹여보고 인간광우병 환자가 나오면(과학적 증거가 확보되면) 그때 가서 조치를 취하는 것이 아니라 미리 예방조치를 취하라는 것이다. 둘째 원칙은 입증 책임의 전환이다. 위험성에 대한 입증을 잠재적 피해자인 우리 국민이 하는 것이 아니라 안전성에 대한 입증을 잠재적 가해자인 미국 정부가 해야 한다는 것이다." (<경향신문> 2008/05/04) 미국산 쇠고기를 먹으면 광우병에 걸린다는 확실한 증거는 없다. 그 증거는 미국산 쇠고기를 먹고 광우병에 걸려야 비로소 확보될 것이다. 그것을 원하는가? 사전의 증거란 없다. 사후의 증거가 있을 뿐이다. 이게 그런 문제다. 왜 그렇게 서둘러야 했을까? 문제는 이명박 정권이 왜 이 원칙을 저버렸는가 하는 것이다. 거기에는 크게 두 가지 이유가 있다. 하나는 한미 FTA의 타결을 위해서다. 한국에서와 달리 미국에서는 FTA가 의회의 반대에 부딪혀 있다. 부시 정권이 FTA에 반대하는 미국 민주당을 설득하려면, 한국 시장에서 미국산 쇠고기의 전면 개방을 관철시켜야 한다. 이명박 정권은 자신이 약속한 경제성장을 위해서는 FTA가 필요하다. 그런 그에게 광우병 타령은 경제성장에 아무 도움도 되지 않는 걸림돌로 여겨질 수밖에 없다. 둘째, 한국에서 쇠고기 문제를 대폭 양보하면, 이명박은 부시 정권의 예쁨을 받을 수 있기 때문이다. 어떤 알 수 없는 이유에서 이명박 정권은 그 동안 "한미관계가 손상됐다"고 주장해 왔다. 이는 물론 한국 내에서 보수층을 결집시키기 위해 유포시킨 '내수용' 이데올로기다. 문제는 이걸 들고 미국까지 갔다는 것이다. 미국의 입장에서는 이명박 정권이 갑자기 한미동맹을 복원하자고 (언제 깨졌었나?) 구애 공세를 해오니, 얼마나 반가웠겠는가? 그 결과 그들은 이명박으로부터 쇠고기 협상에서 대폭 양보를 얻어냈다. 이명박 정권이 이번 방미에서 국가를 위해 얻어온 것은 하나도 없다. 다만, 자신을 위해서 얻어온 것은 있다. 그것은 바로 캠프 데이비드에서 찍은 동영상이다. 광우병의 발생을 최소화하기 위한 장치들을 해제해준 대가로 그는 부시와 골프차를 타고 한미동맹을 과시하는 사진을 얻었다. 실제로 방미 직후 그의 지지율은 살짝 올랐었다. 한 마디로 그는 '국민보건'을 위한 장치를 희생시키는 대가로 자기의 지지율을 챙긴 셈이다. 대중이 분노하는 것은 바로 그 때문이다. 쇠고기 시장 내주면서 이명박 정권이 얻으려 했던 게 또 하나 있었다. 미국의 지원을 받아 북에 대한 압박을 강화하는 것이었다. 그가 전 정권이 북한과 했던 모든 약속을 부정하고, 북에 대해 강경한 발언을 쏟아냈던 것도 미국을 믿었기 때문이었다. 하지만 그가 모르는 새 미국과 북한은 싱가포르에서 이미 테러지원국 해제 절차를 밟기로 4.8협정을 맺었다. 한 마디로, 한미공조를 꿈꾸며 갔다가 북미공조의 현실을 본 것이다. 그가 미국에서 부랴부랴 '남북연락사무소'를 설치하자는 썰렁한 제안을 내놓은 것은 그 때문이다.(시사IN 2008.04.21) 이 모든 얘기를 한 마디로 요약하면, '이명박은 미국 가서 븅딱질 하고 왔다'가 될 것이다. (한나라당에서는 과거에 '등신 외교'라는 표현을 사용했던 것으로 기억한다.) 그 닭짓의 가련한 희생자가 바로 대한민국 국민이다. 그 뿐인가? 주변국에 민폐까지 끼쳤다. 미국에서 쇠고기를 수입하는 이웃나라들도 이명박 정권 때문에 앞으로 협상과정에서 미국에게 덩달아 많이 시달리게 됐다. 이러니 탄핵 얘기가 안 나오겠는가? 탄핵 요구의 정치적 배후 탄핵운동의 정치적 배후는 이미 밝혀져 있다. 경기도의 어느 고등학교에 다니는 학생이란다. 얼마나 무서운가? 누차 얘기하지만, 이번 탄핵 사태에 정치적 배후란 없다. 배후가 있다면, 그 동안 쌓이고 쌓였던 대중의 불만이다. 집권한 지 두 달밖에 안 지났는데, 20년은 지난 것 같다는 대중의 피로감. 그것이 쇠고기 사태를 계기로 한꺼번에 터져 나온 것이다. 어느 정치세력도 이를 예상하지 못했다. 내 경우에도 대운하사업 착수를 계기로 불만이 폭발할 것이라 예상했었다. 미국산 쇠고기 문제는 얼마 전까지만 해도 축산농가의 생존에 관한 문제였다. 그런데 MBC <PD수첩>을 보고, 대중은 비로소 그것을 자기 자신의 문제로, 자기 아이의 문제로 느끼게 된 것이다. 대중은 불안해한다. 하지만 그것은 미국산 쇠고기 자체가 아니라, 그것이 들어오는 절차의 허술함에 대한 불안감이다. 하지만 시위 현장에 나온 대중들은 패닉에 빠져 이성을 잃은 군중의 모습이 아니었다. 그들은 자신들의 분노를 축제로 승화시키고 있었다. 그들은 자신들의 불안을 정권에 대한 즐거운 야유로 표출하고 있다. 거대한 에너지는 광우병에 대한 과장된 공포에서 나오는 게 아니다. 이 분노가 미국산 쇠고기가 안전하다는 관제 계몽을 통해 잠재워질 수 있다고 생각하면 오산이다. 미국산 쇠고기에 대한 불안보다 더 큰 것이 협상 테이블에서 이명박 정권이 보여준 한심함에 대한 야유와 분노다. 이 거대한 열기는, 정권의 닭짓이 미국산 쇠고기 문제에만 국한된 게 아니라, 거의 모든 분야에 걸쳐 자행되는 보편적 닭짓이라는 사실과 관계가 있다. 내 관찰에 따르면, 이명박 정권은 아무 일도 안 할 때 가장 잘 하고 있다. 아무 일도 가장 많이 안 할 수 있는 방법은 역시 잠을 자는 것이다. 문제는 한국의 대통령은 도대체 잠이 없다는 데에 있다. 그가 깨어 있는 시간이 남달리 길다는 데에 대한 불안감. 그것이 저 뜨거운 열기의 정치적 배후다. 썰렁하게 쇠고기가 안전하다는 계몽운동을 할 때가 아니다. 지금 정부에서 할 일은 일단 사과를 하고, 재협상의 길을 모색하는 것이다. 그 외의 기동은 불필요하다. |
진중권/중앙대 겸임교수 |