2010-07-19 2 views
0

최근에 (로거 클래스에서 사용되는)이 함수를 발견했습니다. 나는 그것이 무엇을 이해하지만 난 방법을 모르는 : C stdarg 매크로 이해 (va_start ...)

void Reporter::print(const char* szFormat, ...) { // note: m_out is a FILE* va_list args; va_start(args, szFormat); vfprintf(m_out, szFormat, args); va_end(args); } 

내가 reference를 읽을 수 있지만 여전히 내게 불분명하다. 가장 큰 괴롭힘은 예상대로 작동하지 않는다는 것입니다. 0보다 큰 숫자와 파일 경로를 출력해야하지만 마지막 숫자는 0이고 문자열은 (null)입니다.

사례 1 :

rep.print("Values: %08X %08X %08X %08X %08X %08X %d %s\n", val1, val2, val3, val4, val5, val6, source.GetLength(), szPath); 
// source.GetLength() returns a size_t, szPath is a const char* and IS indeed a valid string 

그러나이로 변경하면 잘 작동 :

사례 2 : 내가 ++ 2008 MSVC에서 컴파일하고있어

rep.print("Values: %08X %08X %08X %08X %08X %08X", val1, val2, val3, val4, val5, val6); 
rep.print(" %d %s\n", source.GetLength(), szPath); 

참고. 동일한 코드가 gcc에서 잘 작동합니다 (첫 번째 경우조차도). Reporter :: print() 또는 함수를 사용하는 방식의 버그가 있습니까? 첫 번째 경우처럼 호출해도 제대로 작동하는지 어떻게 확인할 수 있습니까? 왜 실패 하는가?

+1

MSVC의 버그라고 추측합니다. –

+0

모든 val 변수는 어떤 유형입니까? – JeremyP

+0

그들 모두는'unsigned long'의 – PeterK

답변

3

Reporter::print의 코드는 정상입니다. 이 작업을 수행 할 때마다 가변 인수 목록을 참조하도록 args을 올바르게 초기화 한 다음 해당 변수 인수 목록을 vfprintf()에 전달하면 처리 할 수있는 것이 있습니다.

귀하의 문제는 (AN int 유형의 인수가 필요합니다)를 %d 형식 지정자는 (아마도 size_t이다 나는 짐작 것) source.GetLength()에 의해 반환 된 값의 유형과 일치하지 않습니다 가능성이 높습니다. 이 변수 인수 목록의 일부입니다 인수의 예상되는 형태가 아니기 때문에 그렇다 (

..., (int)source.GetLength(), ... 

: 당신이 길이는 항상 int에 맞는 알고 있다면, 당신은 캐스트 변환으로 해결할 수 일반적인 프로토 타입 함수 선언과 달리 컴파일러에 알려짐).

+0

입니다. size_t입니다. (제 질문에서 언급했습니다). 불행히도, 이것은 도움이되지 못했습니다. 실제로 충돌이 발생했습니다 (MS 런타임 라이브러리 (msvcr90d.dll)에서 액세스 위반). 'case 2' 코드가 사용되면 모든 것이 잘 작동합니다. 정말 이상해. (그리고 나는 많은 파일에서 그것을 실행하고있어, 그래서 이것이 정상적인 행운이 아니길 바란다.) – PeterK

+0

Ok 죄송합니다. (디버깅하는 동안 형식 문자열이 엉망입니다 ... 빠른 편집, 오 소년). 이것은 정말로 그랬다.'size_t'는 어떻게 든 함수에 혼란 스러웠다. int로 캐스팅하면 문제가 해결됩니다. 감사! – PeterK