define 된 값을 역으로 알아내려면?
글쓴이: ssehoony / 작성시간: 금, 2005/02/25 - 3:26오후
다음 과 같이
#define ERR_RETRY 132
int GetError()
{
return ERR_RETRY;
}
printf("ErrCode[%d]\n", GetError());
define 된 값을 찍어서 에러를 확인하는 방법을 사용하는데요.
저렇게 해서 132 라는 값을 얻으면 다시 헤더파일을 참조해서
132 가 무슨 에러인지를 확인해야 하는 번거러움이 있습니다.
(에러핸들링뿐만이 아니고 다른 많은 경우에도)
그래서 이런 macro 를 하나 말 수 없을까 라는 생각을 했죠.
#define mydefine(def_str, def_int)
이런 매크로를 만들어서
mydefine(ERR_RETRY, 132); mydefine(ERR_WAIT, 133);
이렇게 소스를 입력하면
#define ERR_RETRY 132
#define ERR_RETRY 133
const char* def2str(int def_int)
{
if(def_int == 132) return "ERR_RETRY";
if(def_int == 133) return "ERR_WAIT";
return NULL;
}이와 같은 결과가 나오도록 할 수 없을까 하고요.
헌데 좋은 수를 도통 알 수가 없어 조언을 듣고자 이렇게 질문을 올립니다.
꼭 이 방법이 아니더라도 같은 효과를 얻을 수 있는 방법은 없을까요?
Forums:


글쎄요.
결국 님이 하신 방법대로 하는 수밖에 없지 않을까요?
printf("error is %s\n", def2str(err));이렇게 출력하게 하고
err string 은 if 문으로 하지 말고
아예 가능한 err string 을 배열로 만들어서
const char* err_string[] = {
...
};
err code 를 index 로 사용해서 return 하게끔이요
개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?
cpp 로.. 전처리기만 통과시키시고.. 어떻게 변했는지 보시면 되겠죠
cpp 로.. 전처리기만 통과시키시고.. 어떻게 변했는지 보시면 되겠죠 :)
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...
http://mytears.org ~(~_~)~
나 한줄기 바람처럼..
배열로 처리할 수도 있겠으나 C++을 쓰신다면 map도 괜찮은 해결책으로
배열로 처리할 수도 있겠으나 C++을 쓰신다면 map도 괜찮은 해결책으로 보입니다.
제가 요긴하게 쓰는 boost의 assign도 같이 썼습니다.
#include <map> #include <boost/assign/list_of.hpp> enum ErrorCode { err_retry = 132, err_cancel = 133 }; #define ENTRY(item) (item, #item) typedef const std::map<ErrorCode, const char*> Dictionary; Dictionary dictionary = boost::assign::map_list_of ENTRY(err_retry) ENTRY(err_cancel); const char* error_string(ErrorCode error) { Dictionary::const_iterator it = dictionary.find(error); if (it != dictionary.end()) return it->second; else return "unknown error"; }if else 를 반복하는 것 보다 map 이나 배열을 이용한 인덱싱이
if else 를 반복하는 것 보다 map 이나 배열을 이용한 인덱싱이 좋겠군요.
그럼 이제 남은 중요한 사항은
define 을 위해 소스를 define 부분과 역으로 표시해 주는 부분 두 곳을 고치는게 번거럽다는거죠.
이걸 한번에 해결할 좋은 방법이 뭘까? 가장 큰 고민인데요.
일단 제가 봉착한 문제는
#define mydefine(def_name, def_value) #define def_name def_value
이와 같이 매크로 안에 #define 같은 걸 사용 할 수 가 없네요.
#define 를 문자열로 인식하게 할 수 있는 방법이 마련되어 있을 듯 한데.
여기저기 전처리기에 대한 문서를 뒤적거렸는데 못 찾겠네요.
현제 제가 프로젝트에서 사용하고 있는 방법으로매크로를 좀 과하게 사용
현제 제가 프로젝트에서 사용하고 있는 방법으로
매크로를 좀 과하게 사용하여 에러 명세 헤더화일로 부터
컴파일 타임에 string 변환소스부를 생성합니다.
filename : uec.h
에러 명세를 기술 합니다.
#if !defined(UEC_H) || defined(U_GEN_ENUM_STR) #include "umacro_local.h" /** * error codes * @enum UEc Error Code */ U_START_TYPEDEF_ENUM( UEc ) { U_ENUM_DEF( U_ERR, -1, "ERR" ) U_ENUM_DEF( U_EAGAIN, -10, "EAGAIN" ) U_ENUM_DEF( U_EINVAL, -11, "EINVAL" ) U_ENUM_DEF( U_EEXIST, -12, "EEXIST" ) U_ENUM_DEF( U_ENOENT, -13, "ENOENT" ) U_ENUM_DEF( U_EFULL, -14, "EFULL" ) U_ENUM_DEF( U_EEMPTY, -15, "EEMPTY" ) U_ENUM_DEF( U_EUNAVAIL , -16, "EUNAVAIL" ) U_ENUM_DEF( U_EINIT, -20, "EINIT" ) U_ENUM_DEF( U_EADDRINUSE, -60, "EADDRINUSE" ) U_ENUM_DEF( U_ENOSUPPORT, -126, "ENOSUPPORT" ) U_ENUM_DEF( U_EUNKNOWN, -127, "EUNKNOWN" ) U_ENUM_DEF_END( UEc, 0 ) } U_END_TYPEDEF_ENUM( UEc ); #endif #ifndef UEC_H /* * normal header content goes here */ #define UEC_H /** * return error code string corresponding to @a ec */ const char* ustr_ec( UEc ec ); #endiffilename : umacro_local.h
이방법의 핵심으로 이 헤더화일을 포함하기전에 U_GEN_ENUM_STR의
정의 여부에 따라 enum type 이나 enum to string 소스를
표현합니다.
filename : main.c
테스트 소스 입니다.
const char* ustr_ec( UEc ec ) { #define U_GEN_ENUM_STR ec #include "uec.h" #undef U_GEN_ENUM_STR } int main() { printf ("%d = %s", U_EAGAIN, ustr_ec( U_EAGAIN ) ); }댓글 달기