int main(int argc, char *argv[] ) vs int main(int argc, char **argv )

Discussion in 'C Programming' started by Hal Styli, Jan 17, 2004.

  1. Hal Styli

    Hal Styli Guest

    Is this a style thing?

    int main(int argc, char *argv[] ) or int main(int argc, char **argv )

    i.e. *argv[] or **argv

    Why choose the latter?
     
    Hal Styli, Jan 17, 2004
    #1
    1. Advertising

  2. Hal Styli

    Joe Wright Guest

    Hal Styli wrote:
    >
    > Is this a style thing?
    >
    > int main(int argc, char *argv[] ) or int main(int argc, char **argv )
    >
    > i.e. *argv[] or **argv
    >
    > Why choose the latter?


    No reason. The two are identical in the context of function parameters.
    I choose one form or the other depending on how I use argv in the
    program.
    --
    Joe Wright http://www.jw-wright.com
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Jan 18, 2004
    #2
    1. Advertising

  3. Hal Styli wrote:

    > Is this a style thing?
    >
    > int main(int argc, char *argv[] ) or int main(int argc, char **argv )
    >
    > i.e. *argv[] or **argv


    Yes, it's a style thing.

    > Why choose the latter?


    It's a style thing. In a formal parameter list context, char *argv[] and
    char **argv mean precisely the same thing. (In other contexts, they do
    not.) Choose the one you think is most meaningful. I prefer **, but some
    prefer *[], and with perfectly sound reasoning for their preference, so who
    am I to tell them they're wrong?

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Jan 18, 2004
    #3
  4. Hal Styli

    pete Guest

    Richard Heathfield wrote:
    >
    > Hal Styli wrote:
    >
    > > Is this a style thing?
    > >
    > > int main(int argc, char *argv[] ) or int main(int argc, char **argv )
    > >
    > > i.e. *argv[] or **argv

    >
    > Yes, it's a style thing.
    >
    > > Why choose the latter?

    >
    > It's a style thing. In a formal parameter list context, char *argv[] and
    > char **argv mean precisely the same thing. (In other contexts, they do
    > not.) Choose the one you think is most meaningful. I prefer **, but some
    > prefer *[], and with perfectly sound reasoning for their preference, so who
    > am I to tell them they're wrong?


    Copying *[] out of the standard, is easier than thinking.

    --
    pete
     
    pete, Jan 18, 2004
    #4
  5. Re: int main(int argc, char *argv[] ) vs int main(int argc, char**argv )

    Richard Heathfield wrote:

    > Hal Styli wrote:
    >
    >
    >>Is this a style thing?
    >>
    >>int main(int argc, char *argv[] ) or int main(int argc, char **argv )

    [snip]
    >>Why choose the latter?

    >
    >
    > It's a style thing. In a formal parameter list context, char *argv[] and
    > char **argv mean precisely the same thing. (In other contexts, they do
    > not.) Choose the one you think is most meaningful. I prefer **, but some
    > prefer *[], and with perfectly sound reasoning for their preference, so who
    > am I to tell them they're wrong?
    >


    I chose *[] because I access elements using array notation instead of
    pointer arithmetic, and I want to make it as easy as possible for me to
    think of argv as an array.

    I do the same thing in my own functions:

    void strrev(char str[]);

    Would reverse an array of char in place, and in that function I would
    treat that array as an array, not as a pointer.

    int crc32(char *buf, int len);

    Would compute the 32-bit cyclical redundancy check of a buffer
    containing character values. Inside the function, I'd treat buf as a
    pointer (stepping through it with buf++, for example).

    It's purely for the benefit of humans, but that's the point, right? :)

    --
    My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
    Note: Rot13 and convert spelled-out numbers to numerical equivalents.
     
    August Derleth, Jan 18, 2004
    #5
  6. August Derleth wrote:

    > Richard Heathfield wrote:
    >
    >> It's a style thing. In a formal parameter list context, char *argv[] and
    >> char **argv mean precisely the same thing. (In other contexts, they do
    >> not.) Choose the one you think is most meaningful. I prefer **, but some
    >> prefer *[], and with perfectly sound reasoning for their preference, so
    >> who am I to tell them they're wrong?
    >>

    > I chose *[] because I access elements using array notation instead of
    > pointer arithmetic, and I want to make it as easy as possible for me to
    > think of argv as an array.
    >
    > I do the same thing in my own functions:
    >
    > void strrev(char str[]);
    >
    > Would reverse an array of char in place, and in that function I would
    > treat that array as an array, not as a pointer.
    >
    > int crc32(char *buf, int len);
    >
    > Would compute the 32-bit cyclical redundancy check of a buffer
    > containing character values. Inside the function, I'd treat buf as a
    > pointer (stepping through it with buf++, for example).


    Perfectly sound reasoning, IMHO.

    > It's purely for the benefit of humans, but that's the point, right? :)


    Absolutely. Once you have what you consider to be a rational approach (and
    here, you clearly do, even if it's one that I don't happen to use myself),
    the important thing is to stick to it. Consistency is the key.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Jan 18, 2004
    #6
  7. Hal Styli

    Sidney Cadot Guest

    Re: int main(int argc, char *argv[] ) vs int main(int argc, char**argv )

    August Derleth wrote:

    > [...snip...]


    > int crc32(char *buf, int len);
    >
    > Would compute the 32-bit cyclical redundancy check of a buffer
    > containing character values.


    Wouldn't it be more appropriate if the return type was unsigned? The
    resulting value denotes a polynome with binary coefficients, and there
    is nothing to justify a special meaning for the sign bit.

    Forthermore, if you use signed ints inside the routine, you are going to
    do bitwise operations on signed numbers, which may give headaches
    concerning portability.

    (By pretty much the same token, I'd make the buf's base type an unsigned
    char.)

    Best regards, Sidney
     
    Sidney Cadot, Jan 18, 2004
    #7
  8. Hal Styli

    John L Guest

    "Richard Heathfield" <> wrote in message news:buda5v$d2q$...
    > August Derleth wrote:
    >
    >
    > > It's purely for the benefit of humans, but that's the point, right? :)

    >
    > Absolutely. Once you have what you consider to be a rational approach (and
    > here, you clearly do, even if it's one that I don't happen to use myself),
    > the important thing is to stick to it. Consistency is the key.
    >


    The important thing is to distinguish between pointers
    to pre-existing arrays, and pointers which will have
    space allocated to them inside the function, and cases
    somewhere between the two. But C provides no way of doing
    this, and half the time the documentation is no help either. :-(

    John.
     
    John L, Jan 18, 2004
    #8
  9. Re: int main(int argc, char *argv[] ) vs int main(int argc, char **argv )

    Sidney Cadot <> wrote in message news:<budvlg$6v7$>...
    > August Derleth wrote:
    >
    > > [...snip...]

    >
    > > int crc32(char *buf, int len);
    > >
    > > Would compute the 32-bit cyclical redundancy check of a buffer
    > > containing character values.

    >
    > Wouldn't it be more appropriate if the return type was unsigned? The
    > resulting value denotes a polynome with binary coefficients, and there
    > is nothing to justify a special meaning for the sign bit.
    >
    > Forthermore, if you use signed ints inside the routine, you are going to
    > do bitwise operations on signed numbers, which may give headaches
    > concerning portability.
    >
    > (By pretty much the same token, I'd make the buf's base type an unsigned
    > char.)


    I'd shoot for...

    unsigned long crc32(const void *, size_t);

    --
    Peter
     
    Peter Nilsson, Jan 18, 2004
    #9
  10. Re: int main(int argc, char *argv[] ) vs int main(int argc, char**argv )

    Sidney Cadot wrote:
    > August Derleth wrote:
    >
    >> [...snip...]

    >
    >
    >> int crc32(char *buf, int len);
    >>
    >> Would compute the 32-bit cyclical redundancy check of a buffer
    >> containing character values.

    >
    >
    > Wouldn't it be more appropriate if the return type was unsigned? The
    > resulting value denotes a polynome with binary coefficients, and there
    > is nothing to justify a special meaning for the sign bit.
    >
    > Forthermore, if you use signed ints inside the routine, you are going to
    > do bitwise operations on signed numbers, which may give headaches
    > concerning portability.
    >
    > (By pretty much the same token, I'd make the buf's base type an unsigned
    > char.)


    I'm certain you're absolutely correct, and I'm also certain I would take
    all that into account were I to actually implement a crc32 function in
    C. But the prototype above was a brief throwaway and not intended to be
    indicative of my coding skills or lack thereof, merely to illustrate a
    minor point of my style.

    Hell, maybe I should put a Standard Disclaimer in my signature. It
    should only run 200-300 lines, max. ;)

    --
    My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
    Note: Rot13 and convert spelled-out numbers to numerical equivalents.
     
    August Derleth, Jan 19, 2004
    #10
  11. Re: int main(int argc, char *argv[] ) vs int main(int argc, char**argv )

    Peter Nilsson wrote:

    > Sidney Cadot <> wrote in message news:<budvlg$6v7$>...
    >
    >>August Derleth wrote:
    >>
    >>
    >>>[...snip...]

    >>
    >>
    >>
    >>> int crc32(char *buf, int len);
    >>>
    >>>Would compute the 32-bit cyclical redundancy check of a buffer
    >>>containing character values.

    >>
    >>Wouldn't it be more appropriate if the return type was unsigned? The
    >>resulting value denotes a polynome with binary coefficients, and there
    >>is nothing to justify a special meaning for the sign bit.
    >>
    >>Forthermore, if you use signed ints inside the routine, you are going to
    >>do bitwise operations on signed numbers, which may give headaches
    >>concerning portability.
    >>
    >>(By pretty much the same token, I'd make the buf's base type an unsigned
    >>char.)

    >
    >
    > I'd shoot for...
    >
    > unsigned long crc32(const void *, size_t);
    >


    That, indeed, would be favorite.

    --
    My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
    Note: Rot13 and convert spelled-out numbers to numerical equivalents.
     
    August Derleth, Jan 19, 2004
    #11
  12. Re: int main(int argc, char *argv[] ) vs int main(int argc, char**argv )

    John L wrote:

    > The important thing is to distinguish between pointers
    > to pre-existing arrays, and pointers which will have
    > space allocated to them inside the function, and cases
    > somewhere between the two. But C provides no way of doing
    > this, and half the time the documentation is no help either. :-(
    >
    > John.
    >
    >


    I agree totally, and I do include fairly large and complete block
    comments in my header files that give an indication of what my function
    expects, what it will do if those conditions are not met (assuming my
    function can tell), and what it will do if everything is nominal.

    The rest, as they say, relies on the kindness of strangers.

    --
    My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
    Note: Rot13 and convert spelled-out numbers to numerical equivalents.
     
    August Derleth, Jan 19, 2004
    #12
  13. Richard Heathfield <> spoke thus:

    > I prefer **, but some
    > prefer *[], and with perfectly sound reasoning for their preference, so who
    > am I to tell them they're wrong?


    Well, considering you've co-written a book and "they" probably haven't,
    maybe your style preferences count a little bit more ;)

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Jan 19, 2004
    #13
  14. Hal Styli

    Dan Pop Guest

    In <4009c8c2_5@127.0.0.1> "Hal Styli" <no_spam@all> writes:

    >Is this a style thing?
    >
    >int main(int argc, char *argv[] ) or int main(int argc, char **argv )


    Yes.

    >i.e. *argv[] or **argv
    >
    >Why choose the latter?


    1. Because it's the *actual* type of argv, *argv[] is merely syntactic
    sugar.

    2. Because it saves one keystroke.

    To the newbie, *argv[] is more intuitive, because it actually reflects
    the common usage of argv. That's why most C books use this notation.

    Once the programmer realises that *argv[] is nothing more than syntactic
    sugar for **argv (which is far from obvious to the newbie), the easier
    to type form may become more attractive.

    Note that this discussion is valid only for argv when used as function
    parameter. In any other context, the two forms have different meanings:

    char **foo; /* a pointer to a pointer to char */
    char *bar[]; /* an array of pointers to char, of unspecified size */

    foo has a complete type, i.e. its size is known by the compiler, and
    therefore sizeof foo is OK anywhere after the declaration of foo.

    bar has an incomplete type, its size is not known until another
    declaration will specify the actual number of array elements:

    fangorn:~/tmp 144> cat test.c
    char *bar[];

    int invalid(void) { return sizeof bar; }

    char *bar[3];

    int main(void) { return sizeof bar; }
    fangorn:~/tmp 145> gcc test.c
    test.c: In function `invalid':
    test.c:3: sizeof applied to an incomplete type

    While this is a contrived example, it is not uncommon to have declarations
    of external arrays of unknown size:

    extern *bar[];

    bar is actually defined in another module and there is no way to tell its
    number of elements at compile time. At run time, either the module
    defining it will export its size to the rest of the program or a sentinel
    value will be used to mark the end of the array (or both, for partially
    initialised arrays).

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Jan 19, 2004
    #14
  15. Hal Styli

    Old Wolf Guest

    > >Is this a style thing?
    > >
    > >int main(int argc, char *argv[] ) or int main(int argc, char **argv )

    >
    > Yes.
    >
    > Note that this discussion is valid only for argv when used as function
    > parameter. In any other context, the two forms have different meanings:
    >
    > char **foo; /* a pointer to a pointer to char */
    > char *bar[]; /* an array of pointers to char, of unspecified size */


    Actually, the discussion is valid for any function parameter, eg if:
    void baz(char *bar[])
    then sizeof(bar) == sizeof(char **). Same goes for:
    void baz(char *bar[9])
    or any other subscript.
     
    Old Wolf, Jan 20, 2004
    #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. Sokar

    main(int argc, char *argv[])

    Sokar, Apr 29, 2005, in forum: C Programming
    Replies:
    13
    Views:
    725
    Emmanuel Delahaye
    Apr 30, 2005
  2. william
    Replies:
    7
    Views:
    419
    Nick Keighley
    Mar 20, 2007
  3. significantBit

    int main(int argc, const char * argv[]) ??

    significantBit, Apr 9, 2008, in forum: C Programming
    Replies:
    2
    Views:
    1,747
    John Bode
    Apr 9, 2008
  4. mlt
    Replies:
    4
    Views:
    678
    James Kanze
    Jun 9, 2009
  5. lkcl
    Replies:
    1
    Views:
    663
    Stefan Behnel
    Jul 1, 2010
Loading...

Share This Page