2016-06-24 1 views
2

va_list에 함수의 첫 번째 인수를 포함 할 수 있습니까? 한 함수에서 다른 함수로 인수를 전달하고 싶습니다.va_list 오브젝트에 첫 번째 인수 포함

int main(){ 
    test(1,2,3,4,5,-1); 
} 

void test(int firstArg, ...){ 
    va_list va; 
    va_start(va, firstArg); 
    passFunction(va); 
} 

void passFunction(va_list va){ 
    int x;  
    while((x = va_arg(ap,int))!=-1){ 
     cout << x << endl; 
    } 
} 

출력 내가 원하는 :

1 
2 
3 
4 
5 

실제 출력 :

2 
3 
4 
5 

명시 적으로 함수에 첫 번째 인수를 전달하지 않고 달성 할 수있는 방법이 있습니까?

+1

는 가변 인자 템플릿을 사용할 수있는 경우, I 그 대신에 사용하도록 제안하십시오. – chris

+1

나는 그들을 사용할 수 없다. 테스트 함수의 인수는 호출하는 C 함수가 있으므로 C와 호환 가능해야한다. –

+1

왜 태그 C++와'cout << x << endl;'로 게시물을 복잡하게 만드나요? C++ 태그를 제거하고'printf ("% d \ n", x);를 사용하는 것을 제안합니다. – chux

답변

0

va_start()에는 고정 매개 변수가 필요하며 지정된 매개 변수 다음에 다음 매개 변수로 초기화됩니다. 함수에는 하나의 고정 매개 변수 만 있기 때문에 va_start()을 사용하여 va_list에 고정 매개 변수를 포함 할 수 없습니다. 고정 매개 변수가 없기 때문입니다.

32 비트에서만 (64 비트가 훨씬 더 복잡하다), 당신은 va_arg를 초기화를 조정할 다음 자신의 소스 파일로 varargs.h 또는 stdargs.h (또는 이에 상응하는 코드)에서 va_start()에 대한 컴파일러의 소스 코드를 복사 할 수 있습니다 그 뒤에 오는 주소가 아닌 지정된 매개 변수 자체의 주소와 비교하십시오.

#ifdef __cplusplus 
#define va_start(ap, parmN) ((void)((ap) = (std::va_list)((char _FAR *)(&parmN)+__size(parmN)))) 
#else 
#define va_start(ap, parmN) ((void)((ap) = (va_list)((char _FAR *)(&parmN)+__size(parmN)))) 
#endif 

그래서 그냥 +__size(parmN) 부분을 제거하는 것입니다 : 예를 들어

, C++ Builder에서, va_start()는 다음과 같이 정의되어 Visual Studio에서

#ifdef __cplusplus 
#define my_va_start(ap, parmN) ((void)((ap) = (std::va_list)((char _FAR *)(&parmN)))) 
#else 
#define my_va_start(ap, parmN) ((void)((ap) = (va_list)((char _FAR *)(&parmN)))) 
#endif 

va_start()는 다음과 같이 정의된다 :

#define _crt_va_start(ap,v) (ap = (va_list)_ADDRESSOF(v) + _INSIZEOF(v)) 
#define va_start _crt_va_start 

전자 + _INSIZEOF(v) 부분 : 당신은 아마 그 va_start() 소스를 얻을 수 있도록

#define my_va_start(ap,v) (ap = (va_list)_ADDRESSOF(v)) 

GCC 실제로, 대신 매크로의 컴파일러 내장 함수를 사용하지만, 생성 된 코드가 cdecl 호출 규칙 (만 호출 규칙 이후 유사해야 그 32 비트에서 가변 인자를 지원)는 컴파일러 전반에 걸쳐 상당히 표준화되어있다.

어느 쪽이든은, 전처리에 의해 생성 된 코드는 거의 같은 끝날 것입니다, 그래서 컴파일러와 호환되는지 당신은, 직접 코딩 할 수 있습니다 :

void test(int firstArg, ...){ 
    va_list va = (va_list) &firstArg; 
    passFunction(va); 
} 
+0

고맙습니다. 매우 도움이되었습니다. –

+0

더미 매개 변수를 추가하고 va_start를 변경하는 대신 passFunction을 호출하는 더미 내부 함수를 사용하는 것이 좋습니다. – user1952500

+0

@ user1952500 : variadic 함수가 다른 가변 함수를 직접 호출 할 수 없기 때문에 dummy 함수를 호출하기 위해 호출 스택을 조작하기 위해 더미 함수가 인라인 어셈블리를 사용해야합니다. –

관련 문제