Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Variable Length Function parameter list

Variable Length Function parameter list

Scheduled Pinned Locked Moved C / C++ / MFC
tutorialquestion
6 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    slacker
    wrote on last edited by
    #1

    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.

    J 1 Reply Last reply
    0
    • S slacker

      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.

      J Offline
      J Offline
      Joaquin M Lopez Munoz
      wrote on last edited by
      #2

      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

      T 1 Reply Last reply
      0
      • J Joaquin M Lopez Munoz

        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

        T Offline
        T Offline
        Todd Smith
        wrote on last edited by
        #3

        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

        T 1 Reply Last reply
        0
        • T 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

          T Offline
          T Offline
          Tim Smith
          wrote on last edited by
          #4

          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 ret

          Specifically in this case, the only reason this works is because EDI was 0. Tim Smith Descartes Systems Sciences, Inc.

          T N 2 Replies Last reply
          0
          • T Tim 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 ret

            Specifically in this case, the only reason this works is because EDI was 0. Tim Smith Descartes Systems Sciences, Inc.

            T Offline
            T Offline
            Todd Smith
            wrote on last edited by
            #5

            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

            1 Reply Last reply
            0
            • T Tim 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 ret

              Specifically in this case, the only reason this works is because EDI was 0. Tim Smith Descartes Systems Sciences, Inc.

              N Offline
              N Offline
              Nish Nishant
              wrote on last edited by
              #6

              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

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups