Thread: Ellipsis va_arg(arglist, mytype)

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    47

    Ellipsis va_arg(arglist, mytype)

    I know the "Ellipsis" is a bad idea, and I wish there was some way to check number of arguments specified or type of parameter. Know any (other than numargs parameter)?

    Anyways, my question is, if I create my own typedef struct, can I use va_arg( arglist, mytype )? Will it cast to properly? I've tried writing it a few different ways but it always complains, or when it compiles it gives a seg fault.

    Code:
    typdef struct
    {
       /*code*/
    }mytype;
    
    int function( mytype *variable1, ... )
    {
        va_list list;
        mytype *variable2
    
        va_start(list, variable1)
        /*Are any of these right?
        variable2 = va_arg( list, mytype );
        variable2 = va_arg( list, *mytype );
        variable2 = va_arg( list, mytype*);
        ?*/ 
       va_end(list)
    }

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You should explain more specifically what your purpose is here, there is probably a better way.

    Notice (int argc, char *argv[]) involves a variable number of arguments by using a pointer array.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Basically the point is that I will have multiple "instances" of my struct and I want to be able to "overload" my memory cleanup function. It seems that casting to (void*) in the va_arg() call, than casting to type *mytype does the trick, i.e. (*mytype)(va_arg(list,*void)).

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    variable2 = va_arg( list, mytype*); would be correct for what you have there.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Ya I didn't really think in my case since i'm using typdef struct and creating multiple instances that i could do it any other way. Unfortunately va_arg just grabs whatever even if there are no more parameters, and I can cast to mytype and read god knows what memory, so this really isn't good. Is there anyway I can refine this, like with sizeof() to at least check what va_arg grabs??
    Last edited by tempster09; 12-06-2009 at 10:24 AM.

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Why can't you just call function multiple times?
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Just because I thought this was a solution, since it doesn't seem to be though I will call it multiple times. Oh well.

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Variadic functions may work, but they are generally to be avoided because they do not enforce type safety like the rest of the language.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  9. #9
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Ya unfortunately, but I am using a variodic function that has integer parameters, and I use a sentinel value to stop grabbing arguments. Still not great, but I'd assume I would never reach a value less than my sentinel since its under 100 when i'm reading god knows what memory.

  10. #10
    Registered User
    Join Date
    Dec 2008
    Location
    Black River
    Posts
    128
    Variadic funcions can typically only work when you design them in such a way that the type and number of arguments can be deduced by previous arguments. This is usually done in 2 ways:

    - The preceding argument contains information on the arguments that are passed. This is the case of printf and the like wherein the format string tells you how many arguments you will get and their types. Additionally, if all the parameters are of the same type, the first argument can be the number of values that are passed.

    - The arguments hold a sentinel value at the end. Usually, this type of variadic funcions accept only pointers, with the last argument being NULL.

    In the last case, if your compiler supports variadic macros, there are ways to bypass the (very annoying) requirement of having to append NULL for every call:

    Code:
    void f(void *p, ...) {
        va_list arglist;
        va_start(arglist, p);
        while(p != NULL)
           {
           /* do something */
           p = va_arg(arglist, void*);
           }
    }
    
    #define F(X, ...)   f(X, ## __VA_ARGS__, NULL)
    
    int main()
    {
       int x, y;
       F(&x, &y);
    }

  11. #11
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    It such an example you can call the function multiple times, or pass an array. No need to use a non type safe feature.

    Variadic functions are good when both the number and type of arguments is variable. Otherwise it is generally better to use other tools.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. what is the meaing of this typedef line..
    By transgalactic2 in forum C Programming
    Replies: 24
    Last Post: 10-26-2008, 12:21 PM