Thread: va_copy

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    14

    va_copy

    Hi, I'd like to know if this will do what I expect on all platforms (standard C99):

    Code:
    void foo1(va_list arguments)
    {
        va_list arg_copy;    
        va_copy(arg_copy,arguments);
        
        ...    some code using va_arg on arg_copy and not on arguments ...
       
        va_end(arg_copy);
    }
    
    void foo2(va_list arguments)
    {
        va_list arg_copy;     
        va_copy(arg_copy,arguments);
    
         ...    some code using va_arg on arg_copy and not on arguments ....
    
        va_end(arg_copy);
    }
    
    void foo(int count, ...)
    {
       va_list arguments;
       va_start(arguments,count);
       foo1(arguments);
       foo2(arguments);
       va_end(arguments);
    }
    Of course what I expect is "arguments" not to be corrupted when it is passed to foo2. I suppose it is OK or else there is a serious problem with the name of this macro, but you never know .

    None of the exemples about va_copy I found treat this particular point, which made me wonder if there is a better way to do it. And considering that I didn't find much information about the various implementation of the va_list type and the va_arg macro, except that there are precisly various ones, that do not always get along with assignations and such (array of pointers of length 1 I think for example) I am rather unsure of this code.

    Thanks.
    EDIT: sorry about the incorrect code, shouldn't try to learn 3 different things at the same time .
    Last edited by P.Phant; 06-19-2003 at 08:48 PM.

  2. #2
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    I'm not sure what 'arguments' is internally. If it contains pointers (which it probably does) then you should use va_copy() to create another copy to mess with. Your code looks safe to me.

    Just some extra information: In a variable list of arguments, all data values are promoted upwards. Unless it's a double, all types should be 4 bytes long. I believe the va_stuff is used to encapsulate the data values on stack so that errors made don't screw up the stack for all other functions. (IMHO)

  3. #3
    Registered User
    Join Date
    Jun 2003
    Posts
    14
    Thanks ygfperson.
    I *think* that for most implementations arguments is simply a pointer to the stack. In this case no problem to assign the address to an other va_list, or to pass the pointer by value and then call va_arg. But from what I understood it can also be an array of length one containing the pointer, and va_arg is performing an indirection. In this case, assignment is simply not legal, and passing the va_list by value is equivalent to passing the pointer by reference so you end up with a mess if you call va_arg in the subfunction. It seems there are also cases where va_start is doing memory allocation.

    This is all to take with extreme caution, I am very unsure of it.

    Thank you very much for the promotion thing, I hadn't seen it .

  4. #4
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    If you're into assembly language, I've written a very primitive printf clone. The source is over at www.flashdaddee.com in the assembly language section. I simply took the number of arguments from printf's char* and copied items off the stack as I needed them, in order. Since the address of the stack is stored until the function ends, problems with too many or too few arguments remain localized. (Ie: the stack is not disrupted.)

    Another thing to consider is type-checking. Variable lists of arguments are not type-checked. In fact, linux uses the ... in its ioctl() (device driver call) function for the sole purpose of avoiding type checking.

  5. #5
    Registered User
    Join Date
    Jun 2003
    Posts
    14
    Thanks again, there seems to be a problem with flashdadee for now and I've been unable to find your code. But though I do not really know much Assembly (yet) I I'll try to look into it.

Popular pages Recent additions subscribe to a feed