stdarg problems

Discussion in 'C++' started by Obnoxious User, Jul 1, 2007.

  1. On Sun, 01 Jul 2007 15:50:50 +0000, nariknahom wrote:

    > Hi,
    >
    > Can someone tell me what is wrong with the below program?
    > -------------------------------------------
    > int main()
    > {
    > f1( 25 > 50,"testing stdarg. ", "it is working", "if it is
    > working." );
    > return 0;
    > }
    >
    > void f1(bool condition, const char * msg,...)
    > {
    > va_list ap;
    > va_start(ap, msg);
    >
    > while (msg != 0 )
    > {
    > cout<< msg<<endl;
    > msg = va_arg(ap, const char *);
    > }
    > va_end(ap);
    >
    > }
    > --------------------------------------------
    >
    > the ouput is
    > ------------------------------------------
    > testing stdarg.
    > it is working
    > if it is working.
    > 
    > UH??AWAVAUATSH??8H?E?
    > ------------------------------------------
    >


    Cleaned up and compilable version of your code.

    #include <cstdarg>
    #include <iostream>

    void f1(bool condition, const char * msg,...)
    {
    va_list ap;
    va_start(ap, msg);
    while (msg != 0 )
    {
    std::cout<< msg<<std::endl;
    msg = va_arg(ap, const char *);
    }
    va_end(ap);
    }

    int main()
    {
    f1( 25 > 50,"testing stdarg. ", "it is working", "if it is working.",0 );
    return 0;
    }

    --
    Obnoxious User
    Obnoxious User, Jul 1, 2007
    #1
    1. Advertising

  2. Obnoxious User

    Guest

    Hi,

    Can someone tell me what is wrong with the below program?
    -------------------------------------------
    int main()
    {
    f1( 25 > 50,"testing stdarg. ", "it is working", "if it is
    working." );
    return 0;
    }

    void f1(bool condition, const char * msg,...)
    {
    va_list ap;
    va_start(ap, msg);

    while (msg != 0 )
    {
    cout<< msg<<endl;
    msg = va_arg(ap, const char *);
    }
    va_end(ap);

    }
    --------------------------------------------

    the ouput is
    ------------------------------------------
    testing stdarg.
    it is working
    if it is working.
    
    UH??AWAVAUATSH??8H?E?
    ------------------------------------------

    Thanks,
    NarikNahom
    , Jul 1, 2007
    #2
    1. Advertising

  3. On Sun, 01 Jul 2007 15:50:50 +0000, nariknahom wrote:

    >
    > void f1(bool condition, const char * msg,...)
    > {
    > va_list ap;
    > va_start(ap, msg);
    >
    > while (msg != 0 )
    > {
    > cout<< msg<<endl;
    > msg = va_arg(ap, const char *);
    > }
    > va_end(ap);
    >
    > }


    You need to know how many arguments you can parse. Your
    code is stepping outside its proper context and into
    uncharted memory, thus printing weird stuff.

    http://www.cppreference.com/stdother/va_arg.html

    --
    Obnoxious User
    Obnoxious User, Jul 1, 2007
    #3
  4. Obnoxious User wrote:

    > On Sun, 01 Jul 2007 15:50:50 +0000, nariknahom wrote:
    >
    >> Hi,
    >>
    >> Can someone tell me what is wrong with the below program?
    >> -------------------------------------------
    >> int main()
    >> {
    >> f1( 25 > 50,"testing stdarg. ", "it is working", "if it is
    >> working." );
    >> return 0;
    >> }
    >>
    >> void f1(bool condition, const char * msg,...)
    >> {
    >> va_list ap;
    >> va_start(ap, msg);
    >>
    >> while (msg != 0 )
    >> {
    >> cout<< msg<<endl;
    >> msg = va_arg(ap, const char *);
    >> }
    >> va_end(ap);
    >>
    >> }
    >> --------------------------------------------
    >>
    >> the ouput is
    >> ------------------------------------------
    >> testing stdarg.
    >> it is working
    >> if it is working.
    >> 
    >> UH??AWAVAUATSH??8H?E?
    >> ------------------------------------------
    >>

    >
    > Cleaned up and compilable version of your code.
    >
    > #include <cstdarg>
    > #include <iostream>
    >
    > void f1(bool condition, const char * msg,...)
    > {
    > va_list ap;
    > va_start(ap, msg);
    > while (msg != 0 )
    > {
    > std::cout<< msg<<std::endl;
    > msg = va_arg(ap, const char *);
    > }
    > va_end(ap);
    > }
    >
    > int main()
    > {
    > f1( 25 > 50,"testing stdarg. ", "it is working", "if it is working.",0 );


    I believe this should be

    f1( 25 > 50,"testing stdarg. ", "it is working", "if it is working.",
    static_cast<const char*>(0) );

    To make it guaranteed to work. Variable argument functions are mine fields.

    The reason is that you must use the same type in va_arg as in the call, and
    also because the integer 0 is not required to have the same binary
    representation as a null pointer.

    > return 0;
    > }
    >


    --
    rbh
    Robert Bauck Hamar, Jul 1, 2007
    #4
  5. Obnoxious User

    Rolf Magnus Guest

    wrote:

    > Hi,
    >
    > Can someone tell me what is wrong with the below program?


    This:

    > while (msg != 0 )


    checks for a null argument, but with:

    > f1( 25 > 50,"testing stdarg. ", "it is working", "if it is
    > working." );


    you never supplied one, so your function can't find the end of your argument
    list.
    Rolf Magnus, Jul 1, 2007
    #5
  6. Obnoxious User

    Guest

    On Jul 1, 8:50 am, wrote:
    > Hi,
    >
    > Can someone tell me what is wrong with the below program?
    > -------------------------------------------
    > int main()
    > {
    > f1( 25 > 50,"testing stdarg. ", "it is working", "if it is
    > working." );
    > return 0;
    >
    > }
    >
    > void f1(bool condition, constchar* msg,...)
    > {
    > va_list ap;
    > va_start(ap, msg);
    >
    > while (msg != 0 )
    > {
    > cout<< msg<<endl;
    > msg =va_arg(ap, constchar*);
    > }
    > va_end(ap);
    >
    > }
    >
    > --------------------------------------------
    >
    > the ouput is
    > ------------------------------------------
    > testing stdarg.
    > it is working
    > if it is working.
    >
    > UH??AWAVAUATSH??8H?E?
    > ------------------------------------------
    >
    > Thanks,
    > NarikNahom



    Why don't you try msg != NULL and put , NULL as 4th unnamed argumnent
    in the function call in the main function?
    , Jul 2, 2007
    #6
  7. Obnoxious User

    James Kanze Guest

    On Jul 1, 6:37 pm, Robert Bauck Hamar <> wrote:
    > Obnoxious User wrote:
    > > On Sun, 01 Jul 2007 15:50:50 +0000, nariknahom wrote:


    > > f1( 25 > 50,"testing stdarg. ", "it is working", "if it is working.",0 );


    > I believe this should be


    > f1( 25 > 50,"testing stdarg. ", "it is working", "if it is working.",
    > static_cast<const char*>(0) );


    > To make it guaranteed to work. Variable argument functions are
    > mine fields.


    And C++ offers enough other possibilities that they typically
    aren't needed.

    > The reason is that you must use the same type in va_arg as in
    > the call, and also because the integer 0 is not required to
    > have the same binary representation as a null pointer.


    In practice, I don't know of a single 64 bit machine where they
    have the same representation. The integer 0 is almost always a
    32 bit quantity on 64 bit machines, where as a char const* is a
    64 bit quantity. Depending on how arguments are passed, you may
    end up with a very strange looking pointer if you just pass a 0,
    without the cast.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 2, 2007
    #7
  8. Obnoxious User

    Guest

    So you have to always provide a NULL as the last argument. I thought
    the compiler took care of it.
    Shouldnt the compiler already know that?
    , Jul 2, 2007
    #8
  9. Obnoxious User

    Ron Natalie Guest

    wrote:

    >
    > Why don't you try msg != NULL and put , NULL as 4th unnamed argumnent
    > in the function call in the main function?
    >

    As others pointed out, NULL is an integral constant expression. There's
    no guarantee that it can be retrieved by va_arg as a pointer.

    He needs to use a null pointer value of type const char*.
    Ron Natalie, Jul 2, 2007
    #9
  10. Obnoxious User

    Ron Natalie Guest

    wrote:
    > So you have to always provide a NULL as the last argument. I thought
    > the compiler took care of it.


    No, the compiler has no clue what you want to do. stdarg is pretty
    lame and owes it's history to some very early C implementations of
    printf.

    > Shouldnt the compiler already know that?
    >


    Known what?

    While in C++ the fact that the function is declared with ... in the
    parameter list means that it should be able to pass information like
    the actual types and the number of args, historical compatibility with
    loosy-goosy typed C functions precludes this.
    Ron Natalie, Jul 2, 2007
    #10
  11. Obnoxious User

    Guest

    Is the ellipsis( ... ) a part of C/C++ or stdarg.h? If its part of the
    C/C++, then shouldnt the compiler know where the end of the arguments
    is and automatically insert a NULL? Maybe this is not how C/C++ is
    designed but what are the disadvantages if it is so?
    , Jul 2, 2007
    #11
  12. wrote:

    > Is the ellipsis( ... ) a part of C/C++


    Yes. When C++ was designed, C generally used the syntax

    int foo();

    to declare functions. C had no type checking of the arguments, so this
    means «declare function foo to take any number of arguments, and return an
    int». In really old text books, code would often just declare functions
    from the standard library instead of including the proper header. Foo could
    be defined in another compilation unit as:

    int foo(bar)
    int bar;
    { return do_stuff(bar); }

    As you can see, «any number of arguments» usually means «whatever the
    function expects». Dennis Ritchie has commented on this here:
    http://www.lysator.liu.se/c/chistory.ps.

    For another comment on the implications, I refer to the third commandment:
    http://www.lysator.liu.se/c/ten-commandments.html

    In C++, the function declaration syntax came to use the syntax we know
    today, but to support the concept «any number of arguments», as some C
    library functions use, ... was introduced.

    > or stdarg.h?


    No.

    > If its part of the C/C++, then shouldnt the compiler know where the end of
    > the arguments is


    Yes.

    > and automatically insert a NULL?


    No.

    > Maybe this is not how C/C++ is designed but what are the disadvantages if
    > it is so?


    First of all, what is NULL? In C++, it's an integral constant, while in C,
    it's an implemention defined pointer constant. There's no general way for
    the compiler to know what types a function expects for ..., and it would be
    nice if you could use more than one type in ...? So, while there are no
    general disadvantages, there are no real advantages either. And if you can,
    you should avoid using ... in functions.

    --
    rbh
    Robert Bauck Hamar, Jul 2, 2007
    #12
  13. Obnoxious User

    Rolf Magnus Guest

    wrote:

    > Is the ellipsis( ... ) a part of C/C++ or stdarg.h?


    The ellipsis is part of both C and C++. stdarg.h is too. It provides the
    facilities for using variable argument lists.

    > If its part of the C/C++, then shouldnt the compiler know where the end of
    > the arguments is and automatically insert a NULL?


    What if I want some other way to determine the end, e.g. if NULL pointers
    can be anywhere within the argument list? What if I want to pass integers
    as arguments and not pointers? Which value should be inserted for the final
    argument? How would the compiler know if my function expects an integer or
    a pointer?
    Rolf Magnus, Jul 2, 2007
    #13
  14. Obnoxious User

    James Kanze Guest

    On Jul 2, 2:26 pm, "" <>
    wrote:
    > Is the ellipsis( ... ) a part of C/C++ or stdarg.h? If its part of the
    > C/C++, then shouldnt the compiler know where the end of the arguments
    > is and automatically insert a NULL?


    Why? How? The C++ compiler has no idea as to what conventions
    are being used to determine the number and type of the
    arguments. As Ron pointed out, support for variable args was
    really first designed to handle printf and company. No "NULL"
    is needed, and since the argument types can vary, what type
    should it be if the compiler generated it.

    The ellipsis is present in C++ for historical reasons. When
    dealing with a legacy interface, like printf or execl, conform
    to what that interface requires. And don't use it in new code;
    there are always better solutions.

    > Maybe this is not how C/C++ is
    > designed but what are the disadvantages if it is so?


    Except for the fact that its unimplementable and doesn't make
    sense, nothing.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 3, 2007
    #14
  15. Obnoxious User

    James Kanze Guest

    On Jul 2, 4:47 pm, Robert Bauck Hamar <> wrote:

    > First of all, what is NULL? In C++, it's an integral constant,
    > while in C, it's an implemention defined pointer constant.


    In both languages, it's a "null pointer constant". In both
    languages, the "usual" (and traditional) definition is simply
    "0". In both languages, however, any integral constant
    expression will do the trick. C also allows such expressions
    cast to void*, but except under MS-DOS, it's rather exceptional.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 3, 2007
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Francesco Bochicchio

    Equivalent of stdarg.h but on the calling side ?

    Francesco Bochicchio, Jul 1, 2003, in forum: C Programming
    Replies:
    5
    Views:
    914
    Mark Gordon
    Jul 4, 2003
  2. Clint Olsen

    Using stdarg with unknown types

    Clint Olsen, Oct 27, 2003, in forum: C Programming
    Replies:
    6
    Views:
    413
    Sheldon Simms
    Oct 29, 2003
  3. Mac A. Cody

    Confusion with stdarg

    Mac A. Cody, Jan 3, 2005, in forum: C Programming
    Replies:
    9
    Views:
    438
    Lawrence Kirby
    Jan 4, 2005
  4. Klaus Schneider

    template with stdarg: enum problem

    Klaus Schneider, Oct 12, 2005, in forum: C++
    Replies:
    8
    Views:
    1,007
    Klaus Schneider
    Oct 12, 2005
  5. cman

    stdarg definitions

    cman, Mar 20, 2007, in forum: C Programming
    Replies:
    3
    Views:
    502
    Chris Torek
    Mar 25, 2007
Loading...

Share This Page