2009-08-25 3 views
3

가변 인수 함수를 매크로로 변환하는 방법?

error()

이 함수는 다음과 같이 오류 조건에서 사용됩니다.

error("invalid image width %d and image height %d in GIF file %s",wid,hei,name); 

error() 함수가 호출되었습니다. 다른 인수 (변수 인수 함수)로 다른 장소에서.

함수 접근 방식이 잘 작동합니다.

이제이 함수를 매크로로 변환해야한다면 어떻게 할 수 있습니까? 나는 그것을 시도 :

#define error(format) {va_list args;\ 
    printf("Error: ");\ 
    va_start(args, format);\ 
    vfprintf(stderr, format, args);\ 
    va_end(args);\ 
    printf("\n"); abort()} 

하지만이 인수를 올바르게 인쇄하지 않습니다.

위의 매크로 정의에서 잘못된 점은 무엇입니까?

수정 프로그램은 무엇입니까?

답변

2

, 당신은 같은 매크로를 정의 할 수 있습니다 :

: 당신은 GCC를 사용하는 경우

#define error(...) \  
    fprintf(stderr, "Error: "); \ 
    fprintf(stderr, __VA_ARGS__); \ 
    fprintf(stderr, "\n"); \ 
    abort(); 

또는, 또한으로 사용되는 GNU 스타일의 가변 인자 매크로있다 자세한 내용은

#define error(format, args...) \  
    fprintf(stderr, "Error: "); \ 
    fprintf(stderr, format , ## args); \ 
    fprintf(stderr, "\n"); \ 
    abort(); 

는 참조 http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

업데이트

컴파일러에 가변 매크로 지원이없는 경우 기능상의 접근 방식 인 va_list에 충실해야합니다. 정의를 헤더 파일에 저장하려면 정적 인라인 함수를 사용하고 싶습니까?

#define error(args...) (fputs("Error: ",stdout),printf(args),puts("")) 

C99 사용자는 말할 수있다 :

#define error(...) (fputs("Error: ",stdout),printf(__VA_ARGS__),puts("")) 

을하지만 __VA_ARGS__을 사용하여 some problems있다

static inline void error(const char *fmt, ...) { 
#define PRINT_ERROR 
    va_list args; 
    fprintf(stderr, "Error: "); 
    va_start(args, fmt); 
    vfprintf(stderr, fmt, args); 
    va_end(args); 
    fprintf(stderr, "\n"); 
    abort(); 
#endif 
} 
+0

@shawnchin : 고마워요. MSVC6.0, MSVS-2005 컴파일러에서 시도했지만 가변 인수 매크로를 지원하지 않습니다. GCC가 지원하는 것 같아요,하지만 이걸 지원하는 컴파일러 기반의 컴파일러는 알고 있나요? – goldenmean

+0

@goldenmean :이 사이트에서는 ISO 스타일 Variadic 매크로가 MSVS-2005 Visual C++ (http://msdn.microsoft.com/en-us/library/ms177415(VS.80).aspx)에 소개되었습니다. –

+0

@shawnchin : 컴파일러가이 가변 매크로를 컴파일 할 수 있도록 설정해야하는 특이한 MSVisual Studio 프로젝트 옵션이 있습니까? 몇 가지 옵션을 설정하려고했습니다. (예 : C++로 코드 컴파일) 컴파일러가 이러한 가변 매크로 확장 (C99 확장)을 받아들이도록하는 매크로가 있습니까? – goldenmean

0

매크로는 variadic 인수를 지원하지 않으며 어쨌든 va_list을 사용하면 여기에서 작동하지 않으며 가변적 인 함수 인수에서만 작동합니다.

왜 매크로로 어쨌든 (잘 작동하는) 함수를 바꾸고 싶습니까?

1

여기는 article with some examples on variable arguments used in a macro입니다. 그것은 당신이 찾고있는 것을해야하는 것처럼 보입니다. 매크로에 __VA_ARGS__을 사용할 수 있습니다.

어떤 컴파일러를 사용하고 있습니까?

+0

괜찮을 것 같습니다. 매크로로 완벽하게 좋은 함수 호출을 대체하는 이유는 무엇입니까? 인라인 (in-lining)과는 달리이 코드는 퍼포먼스 나 어떤 경우에도 어떤 변화도 일으키지 않습니다. 괜찮은 코드를 가지고 쓰레기로 바꾸는 것입니다. – Glen

0

많은 컴파일러는 다음과 같이 GNU 스타일의 가변 인자 매크로를 지원합니다

#define error(format,args...) do { \ 
    fprintf(stderr, "error: " format "\n", ##args); \ 
    abort(); \ 
} while(0) 

그러나 휴대 성을 목표로하는 경우, 가변 인자 매크로를 사용하지 마십시오. 컴파일러는 ISO 스타일의 가변 인자 매크로를 지원하는 경우

+0

@Laalto : 감사합니다. MSVC6.0, MSVS-2005 컴파일러에서 시도했지만 가변 인수 매크로를 지원하지 않습니다. GCC가 지원하는 것 같아요,하지만 이걸 지원하는 컴파일러 기반의 컴파일러는 알고 있나요? – goldenmean

+0

나는이 구조를 Metrowerks CodeWarrior와 Windows에서 GCC의 다양한 맛에 사용했다. – laalto

0

당신이 원하는 것을 공통의 확장자가있어, 단순히 물품. 다행스럽게도 GCC 확장을 처리 할 수 ​​있지만 컴파일러 관련 확장을 사용하면 args... 모드가 더 널리 사용됩니다.