당신은 어떻게 만드는 디버그에만 사용하는 함수 변수 목록은?다음과 같은 printf()

StackOverflow https://stackoverflow.com/questions/15240

  •  08-06-2019
  •  | 
  •  

문제

을 만들고 싶 디버깅 기능과 동일한 매개 변수를 사용합니다 printf.하지만 하나에 의해 제거 될 수있는 사전 프로세 동안 최적화되어 있습니다.

예를 들어:

Debug_Print("Warning: value %d > 3!\n", value);

나는 보았다 앞 매크로 만들지 않는 모든 플랫폼에서 사용 가능. gcc 을 지원하들 msvc 하지 않습니다.

도움이 되었습니까?

해결책

저는 아직도 옛날 방식으로 정의하는 매크로(XTRACE,아래)하는 관련 중 a no-op 나 함수 호출로 인수 변수 목록입니다.내부적으로 호출 vsnprintf 을 유지할 수 있도록 printf syntax:

#include <stdio.h>

void XTrace0(LPCTSTR lpszText)
{
   ::OutputDebugString(lpszText);
}

void XTrace(LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[512]; // get rid of this hard-coded buffer
    nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);
    ::OutputDebugString(szBuffer);
    va_end(args);
}

다음 일반적인#ifdef 스위치

#ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif

잘할 수 있는 청소까지 꽤 있지만 그것의 기본 생각입니다.

다른 팁

이것은 어떻게 사용하는 디버그 인쇄 아웃 C++.정의'dout'(디버그)을 다음과 같다:

#ifdef DEBUG
#define dout cout
#else
#define dout 0 && cout
#endif

코드에 사용'dout'처럼'참'.

dout << "in foobar with x= " << x << " and y= " << y << '\n';

는 경우는 전처리기에 대체'dout'가'0&&cout'note << 보다 높은 우선 순위를&&및 단락 회로 평가의 및 전체 라인을 평가하 0.이후 0 를 사용하지 않는 컴파일러 코드를 생성한다.

여기에는 뭔가가 나 C/C++.첫째,당신이 쓰는 함수를 사용하는 varargs 물건(에 있는 링크를 참조하십시오 Stu 의 게시물).그런 다음과 같은 것이 가능합니다.


 int debug_printf( const char *fmt, ... );
 #if defined( DEBUG )
  #define DEBUG_PRINTF(x) debug_printf x
 #else
   #define DEBUG_PRINTF(x)
 #endif

 DEBUG_PRINTF(( "Format string that takes %s %s\n", "any number", "of args" ));

모든 당신을 기억해야를 사용하는 것 두 번 괄호 호출할 때는 디버깅 기능,그리고 전체의 라인을 얻을 것이 제거에서 비-디버깅 코드입니다.

또 다른 재미있는 방법을 stub out 앞 기능:

#define function sizeof

@CodingTheWheel:

거기에 하나의 약간의 문제로 접근 방식이다.고려와 같이 통화

XTRACE("x=%d", x);

이에 디버그 빌드 그러나 릴리스에서 구축 확장됩니다:

("x=%d", x);

완벽하게 합법적인 C 컴파일하고 일반적으로 실행하지 않고 부작용을 하지만 생성한 불필요한 코드.접근법으로 일반적으로 사용을 제거하는 문제입니다:

  1. 들에게 XTrace 기능을 반환 int(단 0 을 반환,반환 값 중요하지 않습니다)

  2. 변경#에서 정의하는#다른 절기:

    0 && XTrace
    

지금 릴리스 버전으로 확장됩니다:

0 && XTrace("x=%d", x);

과 알맞은 최적화 프로그램이 전체 일부 단락 회로 평가하지 못하게 했을 것이 아무것도 후&&에서 실행되고 있습니다.

물론,단지 내가 쓴 마지막 문장을,내가 깨달았는 아마도 원래의 형태 최적화될 수 있도와에서 부작용의 경우,같은 기능 통화로 전달된 매개 변수를 XTrace,그것은 더 나은 솔루션을 수 있습을 것이기 때문인지 확인하는 디버그 및 릴리스 버전에도 동일하게 동작합니다.

C++에서 사용할 수 있습니다 스트리밍 운영을 간소화하는 것:

#if defined _DEBUG

class Trace
{
public:
   static Trace &GetTrace () { static Trace trace; return trace; }
   Trace &operator << (int value) { /* output int */ return *this; }
   Trace &operator << (short value) { /* output short */ return *this; }
   Trace &operator << (Trace &(*function)(Trace &trace)) { return function (*this); }
   static Trace &Endl (Trace &trace) { /* write newline and flush output */ return trace; }
   // and so on
};

#define TRACE(message) Trace::GetTrace () << message << Trace::Endl

#else
#define TRACE(message)
#endif

처럼 사용:

void Function (int param1, short param2)
{
   TRACE ("param1 = " << param1 << ", param2 = " << param2);
}

을 구현할 수 있습 맞춤 추적 출력에서 클래스에 대한 많은 것과 같은 방법으로 수행을 위해 그것을 출력하는 std::cout.

아 vsprintf()었던 것은 내가 누락되었습니다.내가 이것을 사용할 수 있습을 통과하는 변수 목록에게 직접 printf():

#include <stdarg.h>
#include <stdio.h>

void DBG_PrintImpl(char * format, ...)
{
    char buffer[256];
    va_list args;
    va_start(args, format);
    vsprintf(buffer, format, args);
    printf("%s", buffer);
    va_end(args);
}

그런 다음 전체를 감싸는 것에서 매크로입니다.

어떤 플랫폼들은 사용할 수 없습니까?stdarg 는 표준 라이브러리의 일부:

http://www.opengroup.org/onlinepubs/009695399/basedefs/stdarg.h.html

모든 플랫폼을 제공하지 않은 표준을 구현 C(또는 매우,매우 old).사람들을 위해,당신은 당신을 사용해야 varargs:

http://opengroup.org/onlinepubs/007908775/xsh/varargs.h.html

문제의 일부분의 이런 종류의 기능을 종종 필요합 앞 macros.이러한 표준화는 상당히 최근(C99),그리고 많이 old C 컴파일러 지원하지 않는 표준 또는 자신의 특별한 작업 니다.

다음은 디버그에 헤더를 썼다는 몇 가지 멋진 기능:

  • 지원 C99 및 C89 구문을 위한 매크로를 디버깅
  • 사용/사용 안함에 따라 출력 기능을 인수
  • 출력하는 파일 기술자(file io)

참고:몇 가지 이유가 있었 약간의 코드를 포맷 문제입니다.

#ifndef _DEBUG_H_
#define _DEBUG_H_
#if HAVE_CONFIG_H
#include "config.h"
#endif

#include "stdarg.h"
#include "stdio.h"

#define ENABLE 1
#define DISABLE 0

extern FILE* debug_fd;

int debug_file_init(char *file);
int debug_file_close(void);

#if HAVE_C99
#define PRINT(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, format, ##__VA_ARGS__); \
} \
else { \
fprintf(stdout, format, ##__VA_ARGS__); \
} \
}
#else
void PRINT(int enable, char *fmt, ...);
#endif

#if _DEBUG
#if HAVE_C99
#define DEBUG(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, "%s : %d " format, __FILE__, __LINE__, ##__VA_ARGS__); \
} \
else { \
fprintf(stderr, "%s : %d " format, __FILE__, __LINE__, ##__VA_ARGS__); \
} \
}

#define DEBUGPRINT(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, format, ##__VA_ARGS__); \
} \
else { \
fprintf(stderr, format, ##__VA_ARGS__); \
} \
}
#else /* HAVE_C99 */

void DEBUG(int enable, char *fmt, ...);
void DEBUGPRINT(int enable, char *fmt, ...);

#endif /* HAVE_C99 */
#else /* _DEBUG */
#define DEBUG(x, format, ...)
#define DEBUGPRINT(x, format, ...)
#endif /* _DEBUG */

#endif /* _DEBUG_H_ */

이 실:

그것은 당신의 질문에 대답합니다.

데 문제에 걸쳐 올 오늘,나의 솔루션은 다음과 같은 macro:

    static TCHAR __DEBUG_BUF[1024]
    #define DLog(fmt, ...)  swprintf(__DEBUG_BUF, fmt, ##__VA_ARGS__); OutputDebugString(__DEBUG_BUF) 

할 수 있습니다 다음 함수를 호출하는 다음과 같다:

    int value = 42;
    DLog(L"The answer is: %d\n", value);

이것은 내가 무엇을 사용:

inline void DPRINTF(int level, char *format, ...)
{
#    ifdef _DEBUG_LOG
        va_list args;
        va_start(args, format);
        if(debugPrint & level) {
                vfprintf(stdout, format, args);
        }
        va_end(args);
#    endif /* _DEBUG_LOG */
}

는 비용이 절대적으로 아무것도에서 실행할 때 시간 _DEBUG_LOG 깃발을 꺼져 있습니다.

이 TCHAR 버전의 사용자의 응답을 것이다,그래서 작품으로 ASCII(일반다),또는 유니코드 형태(이상 또는 이하).

#define DEBUG_OUT( fmt, ...) DEBUG_OUT_TCHAR(       \
            TEXT(##fmt), ##__VA_ARGS__ )
#define DEBUG_OUT_TCHAR( fmt, ...)                  \
            Trace( TEXT("[DEBUG]") #fmt,            \
            ##__VA_ARGS__ )
void Trace(LPCTSTR format, ...)
{
    LPTSTR OutputBuf;
    OutputBuf = (LPTSTR)LocalAlloc(LMEM_ZEROINIT,   \
            (size_t)(4096 * sizeof(TCHAR)));
    va_list args;
    va_start(args, format);
    int nBuf;
    _vstprintf_s(OutputBuf, 4095, format, args);
    ::OutputDebugString(OutputBuf);
    va_end(args);
    LocalFree(OutputBuf); // tyvm @sam shaw
}

I say,"더 많거나 적은",지 않을 것이기 때문에 자동으로 변환 ASCII 문자열을 인수하 WCHAR 지만,그것은 당신을 얻을의 대부분의 유니코드 긁에 대해 걱정할 필요없이 감싸는 형식 문자열에서(텍스트)또는 이전에 그것 L.

크게 에서 파생 MSDN:검색 마지막 오류 코드

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top