2009-11-03 7 views
2

일부 코드 줄을 디버그 모드에서만 "활성"으로 설정하고 해제 모드에서는 무시해야합니다. 다음과 같은 일을 할 수있는 방법이 있나요 : _TEST_가 정의되지 않은 경우해제 모드에서 자동으로 회선에 댓글을 쓰는 방법은 무엇입니까?

#include <iostream> 
using namespace std; 

#ifdef _TEST_ 
#define _cerr cerr 
#else 
#define _cerr // cerr 
#endif 

int main() { 
    _cerr << "TEST message" << endl; 
} 

있도록 일부 라인은 주석 또는 코드에서 제거됩니다. 주석은 나머지 부분보다 먼저 처리되므로이 코드는 잘못되었습니다. 하지만 #ifdef를 명시 적으로 사용하지 않고 필요한 동작을 얻으려면 어떻게해야합니까?

답변

2

ifdefs가가는 길입니다. 컴파일러가 릴리스 대 디버그 모드인지 어떻게 알 수 있습니까? 전처리 단계 이외에 다른 단계가 전달 될 때? 어떤 다른 단계에서 (템플리트 생성 중에) 코드를 제거/추가 할 수 있습니까? 아마도 템플릿 생성을 사용할 수는 있지만 템플릿을 제어하기 위해 ifdef를 계속 사용해야합니다.

어쩌면 내가 생각하지 못하는 정말 매끄러운 방법이 있지만,이 목적으로 모든 사람들이 ifdefs를 알고/사용합니다. 커브를 던지면 코드를 유지하는 데 드는 인적 비용이 크게 증가합니다.

ifdefs로 고정하십시오.

9

당신은이에 대한 매크로를 사용할 수 있습니다

#ifdef _TEST_ 
#define DEBUG_ONLY(x) x; 
#else 
#define DEBUG_ONLY(x) 
#endif 

int main() { 
    DEBUG_ONLY(cerr << "TEST message" << endl) 
} 
+0

유용한 매크로를 한 매크로에서 세미콜론 같은 코드보다 C++하게 추가하지 –

+4

(추가 강제로 사용자가','DEBUG_ONLY' 절'후) – xtofl

+0

나는이 매크로를 볼 수있는 유일한 문제는 너야 한 문장으로 제한됩니다. 나는 개인적으로'do {x; } while (0)'절은 매크로에서 여러 개의 명령문을 허용합니다 (일부 컴파일러가'while (0)'부분에 대해 불평을하더라도 ... : /) –

0
int main() { 
#ifdef _TEST_ 
    _cerr << "TEST message" << endl; 
#endif 
} 
4

사용이 : 물론

#ifdef _TEST_ 
#define DEBUG_TEST(x) x 
#else 
#define DEBUG_TEST(x) 
#endif 

int main() { 
    DEBUG_TEST(_cerr << "TEST message" << endl); 
} 
0

번호, 아니.

이에 변화를 시도해보십시오. (기본적으로 그냥 입력을 폐기 스트림을 원할 것)

#ifdef _TEST_ 
    ostream& _cerr = cerr; 
#else 
    ostringstream _cerr; 
#endif 

+1

우선, 밑줄 접두어가 붙은 전역 이름을 사용하는 것은 예약되어 있습니다 구현을 위해 나는 믿는다. 두 번째로, 입력을 버리는 스트림은 인수가 평가되는 것을 막지 않으므로 성능에 민감한 환경에서이 접근법을 쓸모 없게 만듭니다. – Tom

1

이 여기에 기본적으로 당신이 무엇을 요구하지 :

#ifdef _TEST_ 
#define _cerr cerr 
#else 
#define _cerr if (1) {} else cerr 
#endif 

예를 들어 만약 당신이 다음과 같이 쓸 때 else이라는 모호한 것에 대한 컴파일러 경고를받는다면 놀랄 필요는 없습니다 :

if (something) 
    _cerr << "Why?" << std::endl; 

_cerr은 사실 아주 단순한 매크로라는 사실을 항상 알고 있어야합니다.

1

_cerr을 nothing으로 정의하면 컴파일이 실패합니다. 대신 릴리스 모드에서 제외하는 매크로를 정의 할 수 있습니다.예를 들어

:

코드에서 다음
#ifdef _TEST_ 
#define LOG_ERROR(log) cerr << log << endl; 
#else 
#define LOG_ERROR(log) 
#endif 

:

int main() { 
    LOG_ERROR("TEST message"); 
} 
+0

그는 아무것도 정의하려고 시도하지 않았습니다. 그는 주석 확장이 매크로 확장에 포함되기를 기대했기 때문에 결과는 주석 처리 된 로깅 라인이됩니다. –

5

당신이 후에있는 것은 릴리스에서 제거 디버그 로깅은 당신과 같이 할 수있는 빌드 인 경우 :

#ifdef _TEST_ 
#define LOG(x) (cerr << x << endl) 
#else 
#define LOG(x) 
#endif 

... 

int main() { 
    LOG("TEST message"); 
} 
0

"no log in in release"에 대한 더 나은 해결책은 다음과 같습니다.

class NullStream { 
    template<typename T> NullStream& operator<< const(T&) { } 
}; 

사용 :

#ifdef DEBUG 
#define CERR std::cerr 
#else 
#define CERR NullStream() 
#endif 
+0

좋지 않음 : 인수가 평가 될 것입니다 ... 쓸모없는 경우에도! –

+0

참이지만, 예를 들어 글을 쓸 때도 문제가 발생합니다. stringstream. 이것은'operator << (ostream &, T)'와'ostreambuf'의 오버 헤드를 줄여줍니다. – MSalters

0

자신의 NULL 스트림을 작성합니다.

#include <iostream> 

class NullStream {}; 
template<typename T> 
NullStream& operator <<(NullStream& n,T const& data)      {return n;} 
NullStream& operator <<(NullStream& n,std::ostream& (*)(std::ostream&))  {return n;} 

#ifdef _TEST_ 
#define myerr  std::cerr 
#else 
NullStream myerrstream; 
#define myerr  myerrstream 
#endif 

int main() 
{ 
    myerr << "Hi" << std::endl;; 
    myerr << std::endl;; 
}