Understanding va_start(ap, v) in STDARG.H

This is a discussion on Understanding va_start(ap, v) in STDARG.H within the C Programming forums, part of the General Programming Boards category; Code: #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) #define va_start(ap,v) ( ap = (va_list)&v ...

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    64

    Understanding va_start(ap, v) in STDARG.H

    Code:
    #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
    #define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
    What type is of v? Not a pointer, I think, otherwise, there is no need to get the address using &v, v itself will suffice.
    Last edited by thinhare; 09-23-2005 at 11:06 AM.

  2. #2
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    v is the the argument before ...
    va_start actually sets the pointer 'ap' to point at the stack memory exactly
    below 'v':
    Code:
    void foo(int a, int b, int c, ...);
    ...
    foo(1,2,3,100,200)
    
    stack:
    <return address>
    200
    100  <-- va_start() sets ap here
    3
    2
    1
    va_start has to know the size of last named argument, v, to set up right.

  3. #3
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    to make the picture more clear:
    Code:
    stack memory inside foo():
    200
    100  <-- va_start() sets 'ap' here
    3   <-- this is &v. we need to increase to size of v to shift to the first unnamed arg
    2
    1
    <return address>
    <foo's prologue>
    <foo's local variables>

  4. #4
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    the _INTSIZEOF(n) macro, I beleive, calculates the size of last named
    argument, 'rounded' to sizeof(int), because v, push-ed on stack before
    call to foo(), is 'rounded' to size. For example, on IA32,
    Code:
    void bar(char c);
    ...
    char c = 1;
    bar(c);
    c is push-ed on stack as 32-bit value, so the size is sizeof(int).
    in case of bar(double d), two 32-bit values are push-ed.

  5. #5
    Registered User
    Join Date
    Dec 2004
    Posts
    64
    I don't get it. valenok.
    After all, I know v is a pointer, and &v is a pointer, too, pointing to somewhere in the stack where v is stored. Thanks!

  6. #6
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    you have to understand how the function call works,
    the stack memory layout before and after the call.
    If you do not get it, there is no chance you'll understand va_start() macro.
    some assembler tutorial on that matter would be in help.

  7. #7
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    first of all, 'v' may not be a pointer.

  8. #8
    cwr
    cwr is offline
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    868
    I already tried to explain this to you here. valenok's explanation is similar. If you are trying to understand C programming, then understanding how va_start is implemented is not necessary.

    Basically, as explained above, the implementation that you showed is taking the address of the last fixed argument and adding the size of it rounded to int, this is to find the address on the stack of the first variable argument.

    This is not something that is portable, but it's okay for the implementation to do this in the implementation code, because the implementation knows about how function calls are done on that architecture. Other implementations may proceed differently.

    Edit:

    Further, to elaborate on valenok's statement that 'v' doesn't have to be a pointer: Try to forget that it is, as I think that it's confusing you. Imagine if 'v' is a char, or a short, or an int, or a double. The va_start implementation doesn't care what type it is, it just takes its size rounded up to an int, and adds the size to the address, so that the next argument on the stack's address is computed.
    Last edited by cwr; 09-26-2005 at 03:57 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Understanding Headers
    By AeonMoth in forum C++ Programming
    Replies: 2
    Last Post: 06-27-2007, 05:53 AM
  3. trouble understanding the source file structure
    By Mario F. in forum C++ Programming
    Replies: 5
    Last Post: 05-26-2006, 06:46 PM
  4. Replies: 8
    Last Post: 10-24-2005, 11:26 AM
  5. understanding recursive functions
    By houler in forum C Programming
    Replies: 7
    Last Post: 12-09-2004, 11:56 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21