Thread: End of a variable argument list

  1. #1
    Registered User GigaRoid's Avatar
    Join Date
    Aug 2011
    Location
    Everywhere
    Posts
    23

    End of a variable argument list

    Noob question: How do you check if you're out of arguments in a variable argument list? I'd like to use it in a loop.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You can't just search a valist to work out the end.

    Either
    - encode the number of parameters, say a format string, like printf -> printf(3): formatted output conversion - Linux man page
    - mark the end of the list with a special value, like execl -> execl(3): execute file - Linux man page

    A third way would be just to make one of the fixed arguments a literal count of the variable args.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by GigaRoid View Post
    Noob question: How do you check if you're out of arguments in a variable argument list? I'd like to use it in a loop.
    I would guess(without knowing your purpose) that putting the arguments in a std::vector would be a better solution for sending a function variable number of values.

  4. #4
    Registered User GigaRoid's Avatar
    Join Date
    Aug 2011
    Location
    Everywhere
    Posts
    23
    Quote Originally Posted by Salem
    Either
    - encode the number of parameters, say a format string, like printf -> printf(3): formatted output conversion - Linux man page
    - mark the end of the list with a special value, like execl -> execl(3): execute file - Linux man page

    A third way would be just to make one of the fixed arguments a literal count of the variable args.
    Quote Originally Posted by manasij7479
    I would guess(without knowing your purpose) that putting the arguments in a std::vector would be a better solution for sending a function variable number of values.
    Sorry, I'm pretty new, and I don't understand how to do either of those. If it helps, I am trying to make my own max function. Just knowing how to do it will be useful.
    Code:
    #include <iostream>
    #include <cstdarg>
    
    using namespace std;
    
    double smax(int num, ...)
    {
        va_list arg;
        int nmax=num;
    
        va_start (arg, num);
        while (!/*INSERT ENDLIST CHECK HERE*/)
        {
            if (nmax<va_arg(arg,double))
            nmax=va_arg(arg,double);
        }
        va_end(arg);
    
        return nmax;
    }
    
    int main()
    {
        cout<<smax(1,2,3,4,5,0)<<endl; //suppost to show the maximum value as a string
    }

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    As mentioned, va_whatever doesn't give you any way to find the end of the list. You need to have your users tell you somehow where the end of the list is, either by telling you how many numbers there are, or by using some sentinel value at the end that you can check for.

    The C++ way to do it, as also mentioned above, is to use a std::vector, which is an object that can be resized at will and that does know start and end. If you don't know anything about std::vector, then now is the time to start reading.

  6. #6
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by GigaRoid
    Sorry, I'm pretty new, and I don't understand how to do either of those. If it helps, I am trying to make my own max function. Just knowing how to do it will be useful.
    Here is an example...of that function..
    Code:
    template<class T>
    T my_max(std::vector<T> v)
    {
        T temp=v[0];
        while(!v.empty())
        {
            if(v.back()>temp)
                temp=v.back();
            v.pop_back();
        }
        return temp;
    }
    Last edited by manasij7479; 08-28-2011 at 02:34 PM.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > cout<<smax(1,2,3,4,5,0)<<endl;
    So does this zero mark the end of the va_list ?

    The 3rd way I mentioned would call this function using.
    cout<<smax(5,1,2,3,4,5)<<endl;

    and inside the function, you would have
    for ( i = 0 ; i < num ; i++ )
    The first parameter is the count of the number of va_args.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User GigaRoid's Avatar
    Join Date
    Aug 2011
    Location
    Everywhere
    Posts
    23
    Quote Originally Posted by mansij7479
    Code:
    template<class T>
    T my_max(std::vector<T> v)
    {
        T temp=v[0];
        while(!v.empty())
        {
            if(v.back()>temp)
                temp=v.back();
            v.pop_back();
        }
        return temp;
    }
    What way can I use this that doesn't give 5 errors?
    Quote Originally Posted by Salem
    The 3rd way I mentioned would call this function using.
    cout<<smax(5,1,2,3,4,5)<<endl;

    and inside the function, you would have
    for ( i = 0 ; i < num ; i++ )
    The first parameter is the count of the number of va_args.
    Okay, that makes sense to me, but how do I check if the number of va_arg!=num instead of the value?

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by GigaRoid View Post
    What way can I use this that doesn't give 5 errors?
    If you use it as given, you get 0 errors. If you are somehow getting 5 errors, then you will have to show us what you've done. (You are using a vector as it says, right? Not just putting a bunch of numbers inside parentheses?)
    Quote Originally Posted by GigaRoid View Post
    Okay, that makes sense to me, but how do I check if the number of va_arg!=num instead of the value?
    I don't know what you mean here, because we are checking the number of va_arg -- or at least, the number of arguments we told you to expect via the first parameter. Are you asking about a sentinel (i.e., the 0 in your example)? va_arg gives you the value of the variable, so you can check it that way.

  10. #10
    Registered User GigaRoid's Avatar
    Join Date
    Aug 2011
    Location
    Everywhere
    Posts
    23
    Quote Originally Posted by tabstop
    If you use it as given, you get 0 errors. If you are somehow getting 5 errors, then you will have to show us what you've done. (You are using a vector as it says, right? Not just putting a bunch of numbers inside parentheses?)
    Once again, I have no idea about this at all, so none of this is completely clear to me.
    va_arg gives you the value of the variable, so you can check it that way.
    So how would I check if the number of arguments is reached?
    Last edited by GigaRoid; 08-28-2011 at 07:26 PM.

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by GigaRoid View Post
    How is the program supposed to know the difference between the number of va_arg and the value of the current va_arg?
    The number of variable arguments is num. num uses many different letters than va_arg (well, three anyway), so the compiler won't have much difficulty distinguishing them. (EDIT: This is assuming we're still talking about Salem's example and not gone somewhere completely different.)

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Just to be clear: if you want the number of elements to be the first argument, Salem gave you exactly the code you need with no modification required. If you are looking for a sentinel value at the end (i.e., 0 ends the list), then you had that at the very beginning and didn't need to ask the question:
    Code:
    while (va_arg(arg, double) != 0)
        if (nmax<va_arg(arg,double))
            nmax=va_arg(arg,double);
    And actually you'd probably want to put do something like doing that va_arg call once into a variable, rather than three times, since we don't want to peel three arguments off the list every time.
    Note that this code probably won't work with your call:
    Code:
    smax(1,2,3,4,5,0)
    since those aren't doubles. You can't get away with that sort of type mismatch with va_arg lists.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There is also the newer std::initializer_list option...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User GigaRoid's Avatar
    Join Date
    Aug 2011
    Location
    Everywhere
    Posts
    23
    I know it's possible for a function to know how many arguments there are without user input. To know how many arguments the loop has gone through you just use
    Code:
    int argnum=1;
    //...
    while (argnum!=mystery_num)
        {
            if (nmax<va_arg(arg,double))
            {
                nmax=va_arg(arg,double);
                argnum++;
            }
    The code just needs to know what mystery_num is. num!=argument_numbers. Or you could replace the 'argnum!=mystery_num' with 'va_arg(arg,double)!=empty_slot'. Checking if there is no value there. Or is it just stored as 0?
    Last edited by GigaRoid; 08-29-2011 at 12:32 PM.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There is no empty slot.
    va_arg is dumb; it simply fetches a value adjacent in memory and increments that position each time you call it.
    It does not know how many arguments were passed nor does it care. That's why it should be avoided.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Variable Argument List
    By vb.bajpai in forum C Programming
    Replies: 2
    Last Post: 06-16-2007, 05:35 AM
  2. Passing Through A Variable Argument List
    By SMurf in forum C Programming
    Replies: 6
    Last Post: 04-14-2007, 11:12 AM
  3. Variable Argument List Passing
    By Orborde in forum C++ Programming
    Replies: 2
    Last Post: 05-10-2005, 08:42 PM
  4. I'll have a Variable argument list to go...
    By SMurf in forum C Programming
    Replies: 6
    Last Post: 02-27-2003, 02:02 PM
  5. variable-length argument list ???
    By null in forum C Programming
    Replies: 5
    Last Post: 10-14-2001, 03:18 PM