2012-10-23 2 views
0

C89 GCC 4.7.4형식화하는

안녕하세요,

난 그냥 이런 매크로를 실험 하였다

#define LOG_INFO_1(fmt, ...) printf(fmt, __VA_ARGS__) 
#define LOG_INFO_2(...) printf(__VA_ARGS__) 

그리고 다음과 같이 사용 :

LOG_INFO_1("%s:%d", __func__, __LINE__); 
LOG_INFO_2("%s:%d", __func__, __LINE__); 

출력 결과가 정확히 동일합니다. 첫 번째 매크로에 fmt 인수를 사용하면 어떤 이점이 있는지 궁금합니다. 그것은 정말로 필요한 것 같지 않습니다. 내가 어떻게 그것을 사용할 수 있을까? 어떤 제안에 대한

많은 감사합니다, 당신이 사용 변주는 중요하지 않습니다 매크로에 대한

+2

형식 문자열 만 전달하려는 경우에는 차이가 있습니다. 'LOG_INFO_1 ("단순한 문자열")'. 그렇게하면'LOG_INFO_2'가 올바르게 확장되는 반면'LOG_INFO_1'는'printf' ('__VA_ARGS__'가 빈 문자열로 확장되기 때문에)의 후행 쉼표로 인해 컴파일러 오류가 발생합니다. –

답변

5

첫 번째 매개 변수가 fmt 인 것을 지정하면 컴파일러/컴퓨터에 아무런 차이가 없습니다.

그러나 코드를 사용하는 다른 프로그래머에게는 큰 차이가 있다고 생각합니다.

LOG_INFO_1(fmt, ...)에서 보았을 때이 매크로는 추가 매개 변수가있는 printf 스타일 형식 문자열을 사용한다는 강력한 힌트가 있습니다.

LOG_INFO_2(...)에서 보았을 때 어떤 매개 변수를 전달해야하는지, 어떤 순서로 전달해야하는지 알지 못합니다. 첫 번째 매개 변수는 RFC 5424 심각도 코드 여야합니까? 어쩌면 그것은 출력 스트림을 작성해야합니까? 매크로에서 아무 것도 대답을 암시하지 않습니다.

가능한 한 많은 것을 지정하고 절대적으로 필요한 부분에만 ... 등의 모호성을 남기고 나서는 프로그래머가 더 쉽게 작업해야한다고 생각합니다.

2

. 전 처리기는 두 매크로에서 동일한 C 코드를 생성합니다.


가변 인수 함수의 경우 적어도 하나의 인수가 정의되어야합니다.

그래서

void foo(const char * fmt, ...); 

컴파일 할

,

반면
void bar(...); 

하지 않을 것입니다.

1

ACE_DEBUG/Log_Msg을 살펴보십시오. ACE (적응 형 통신 환경)는 네트워킹을위한 확립 된 C++ 프레임 워크입니다. 그들은 비슷한 방법으로 매크로와 가변 변수를 사용하여 스레드 안전 로깅 아키텍처를 구현했습니다.

관련 문제