Variable Length Function parameter list
-
Does anybody know how to get the number of arguments from a variable length function parameter list? I can't seem to find any documentation anywhere about how to get then number or arguments, without the number of args being a parameter itself.
You can't. The number (and type) of arguments has to be deduced from one of the non-variable arguments supplied, like, for instance,
printf
does with its first format argument. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
You can't. The number (and type) of arguments has to be deduced from one of the non-variable arguments supplied, like, for instance,
printf
does with its first format argument. Joaquín M López Muñoz Telefónica, Investigación y DesarrolloActually, you can.
int CountArgs(char* unused, ...)
{
int count = 0;va\_list args; va\_start(args, unused); for (char\* cp = va\_arg(args, char\*); cp; cp = va\_arg(args, char\*)) { count++; } va\_end(args); return count;
}
int main()
{int numArgs = CountArgs("blah", "1", "2", "3", "4"); return 0;
}
You could also use the first variable to indicate how many variables you are passing in.
CountArgs(int numArgs, ...);
Todd Smith
-
Actually, you can.
int CountArgs(char* unused, ...)
{
int count = 0;va\_list args; va\_start(args, unused); for (char\* cp = va\_arg(args, char\*); cp; cp = va\_arg(args, char\*)) { count++; } va\_end(args); return count;
}
int main()
{int numArgs = CountArgs("blah", "1", "2", "3", "4"); return 0;
}
You could also use the first variable to indicate how many variables you are passing in.
CountArgs(int numArgs, ...);
Todd Smith
That the will NOT work reliably. If you look at the code generated, there isn't a NULL pushed onto the stack. Thus, just by luck does this work when it does.
19: int main()
20: {
004010B0 push ebp
004010B1 mov ebp,esp
004010B3 sub esp,44h
004010B6 push ebx
004010B7 push esi
004010B8 push edi
004010B9 lea edi,[ebp-44h]
004010BC mov ecx,11h
004010C1 mov eax,0CCCCCCCCh
004010C6 rep stos dword ptr [edi]
21: int numArgs = CountArgs("blah", "1", "2", "3", "4");
004010C8 push offset string "4" (00422030)
004010CD push offset string "3" (0042202c)
004010D2 push offset string "2" (00422028)
004010D7 push offset string "1" (00422024)
004010DC push offset string "blah" (0042201c)
004010E1 call @ILT+5(CountArgs) (0040100a)
004010E6 add esp,14h
004010E9 mov dword ptr [ebp-4],eax
22: return 0;
004010EC xor eax,eax
23: }
004010EE pop edi
004010EF pop esi
004010F0 pop ebx
004010F1 add esp,44h
004010F4 cmp ebp,esp
004010F6 call __chkesp (00401120)
004010FB mov esp,ebp
004010FD pop ebp
004010FE retSpecifically in this case, the only reason this works is because EDI was 0. Tim Smith Descartes Systems Sciences, Inc.
-
That the will NOT work reliably. If you look at the code generated, there isn't a NULL pushed onto the stack. Thus, just by luck does this work when it does.
19: int main()
20: {
004010B0 push ebp
004010B1 mov ebp,esp
004010B3 sub esp,44h
004010B6 push ebx
004010B7 push esi
004010B8 push edi
004010B9 lea edi,[ebp-44h]
004010BC mov ecx,11h
004010C1 mov eax,0CCCCCCCCh
004010C6 rep stos dword ptr [edi]
21: int numArgs = CountArgs("blah", "1", "2", "3", "4");
004010C8 push offset string "4" (00422030)
004010CD push offset string "3" (0042202c)
004010D2 push offset string "2" (00422028)
004010D7 push offset string "1" (00422024)
004010DC push offset string "blah" (0042201c)
004010E1 call @ILT+5(CountArgs) (0040100a)
004010E6 add esp,14h
004010E9 mov dword ptr [ebp-4],eax
22: return 0;
004010EC xor eax,eax
23: }
004010EE pop edi
004010EF pop esi
004010F0 pop ebx
004010F1 add esp,44h
004010F4 cmp ebp,esp
004010F6 call __chkesp (00401120)
004010FB mov esp,ebp
004010FD pop ebp
004010FE retSpecifically in this case, the only reason this works is because EDI was 0. Tim Smith Descartes Systems Sciences, Inc.
Tim is correct. So I would either pass the # args as the first parameter (what I usually do anyways) or if it makes sense require the last parameter to be 0.
Todd Smith
-
That the will NOT work reliably. If you look at the code generated, there isn't a NULL pushed onto the stack. Thus, just by luck does this work when it does.
19: int main()
20: {
004010B0 push ebp
004010B1 mov ebp,esp
004010B3 sub esp,44h
004010B6 push ebx
004010B7 push esi
004010B8 push edi
004010B9 lea edi,[ebp-44h]
004010BC mov ecx,11h
004010C1 mov eax,0CCCCCCCCh
004010C6 rep stos dword ptr [edi]
21: int numArgs = CountArgs("blah", "1", "2", "3", "4");
004010C8 push offset string "4" (00422030)
004010CD push offset string "3" (0042202c)
004010D2 push offset string "2" (00422028)
004010D7 push offset string "1" (00422024)
004010DC push offset string "blah" (0042201c)
004010E1 call @ILT+5(CountArgs) (0040100a)
004010E6 add esp,14h
004010E9 mov dword ptr [ebp-4],eax
22: return 0;
004010EC xor eax,eax
23: }
004010EE pop edi
004010EF pop esi
004010F0 pop ebx
004010F1 add esp,44h
004010F4 cmp ebp,esp
004010F6 call __chkesp (00401120)
004010FB mov esp,ebp
004010FD pop ebp
004010FE retSpecifically in this case, the only reason this works is because EDI was 0. Tim Smith Descartes Systems Sciences, Inc.
Yikes!!!!!!! For a moment I thought I was in the wrong web site :-) Nish Sonork ID 100.9786 voidmain www.busterboy.org If you don't find me on CP, I'll be at Bob's HungOut