Why is it int argc?

Discussion in 'C Programming' started by MartinBroadhurst, Feb 7, 2011.

  1. I've never used a negative number of command line arguments.

    Martin
    MartinBroadhurst, Feb 7, 2011
    #1
    1. Advertising

  2. MartinBroadhurst <> writes:
    > I've never used a negative number of command line arguments.


    I think the argc/argv convention predates the introduction of unsigned
    int into the language. (In ancient versions of C, I think it was common
    to use pointers when you needed to do unsigned arithmetic.)

    Using a signed type might also make some idioms a bit easier; for
    example, a test for argc >= 0 would always (appear to) succeed if argc
    were unsigned.

    Finally, have you ever used more than INT_MAX command line arguments?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Feb 7, 2011
    #2
    1. Advertising

  3. On Feb 7, 10:25 pm, Keith Thompson <> wrote:
    > MartinBroadhurst <> writes:
    > > I've never used a negative number of command line arguments.

    >
    > I think the argc/argv convention predates the introduction of unsigned
    > int into the language.  (In ancient versions of C, I think it was common
    > to use pointers when you needed to do unsigned arithmetic.)
    >


    That seems a likely explanation.

    > Using a signed type might also make some idioms a bit easier; for
    > example, a test for argc >= 0 would always (appear to) succeed if argc
    > were unsigned.
    >


    Are there implementations in which argc can be 0 then?

    > Finally, have you ever used more than INT_MAX command line arguments?
    >


    Not unless I've perpetrated some sort of console pasting disaster. I
    wasn't so concerned about the efficiency of using an unnecessarily
    large type, more the semantics.

    Martin
    MartinBroadhurst, Feb 7, 2011
    #3
  4. MartinBroadhurst <> writes:
    > On Feb 7, 10:25 pm, Keith Thompson <> wrote:
    >> MartinBroadhurst <> writes:
    >> > I've never used a negative number of command line arguments.

    >>
    >> I think the argc/argv convention predates the introduction of unsigned
    >> int into the language.  (In ancient versions of C, I think it was common
    >> to use pointers when you needed to do unsigned arithmetic.)
    >>

    >
    > That seems a likely explanation.


    See, for example, <http://cm.bell-labs.com/cm/cs/who/dmr/cman.pdf>,
    in which the only numeric types were char, int, float, and double.
    (On the other hand, I just noticed that document doesn't mention
    argc and argv.)

    Even as late as C90, int was considered the default type for many
    things; you might define main as:

    main(argc, argv)
    char **argv;
    {
    ...
    }

    >> Using a signed type might also make some idioms a bit easier; for
    >> example, a test for argc >= 0 would always (appear to) succeed if argc
    >> were unsigned.
    >>

    >
    > Are there implementations in which argc can be 0 then?


    Yes the standard permits argc to be 0 (C99 5.1.2.2.1p2: "The value
    of argc shall be nonnegative.") In that case, the program name is
    not available, at least not via argv[0].

    And on POSIX-based systems, the exec() family of functions lets you
    invoke a program with pretty much any argc and argv values you like.

    But what I actually had in mind is that argc is modifiable.
    I've seen code that steps through the arguments by repeatedly
    decrementing argc and incrementing argv. It's not the way I'd do
    it, but it's valid nonetheless.

    >> Finally, have you ever used more than INT_MAX command line arguments?
    >>

    >
    > Not unless I've perpetrated some sort of console pasting disaster. I
    > wasn't so concerned about the efficiency of using an unnecessarily
    > large type, more the semantics.


    Well, both int and unsigned int are the same size. Both have a
    range that covers any reasonable number of arguments. int has the
    advantage that the lower and upper bounds are both well outside any
    reasonable requirement; unsigned int's lower bound of 0 is right
    at the edge, which might be error-prone in some cases. But that's
    not a very strong argument (if argc were unsigned, we'd get by),
    nor is it the actual rationale.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Feb 7, 2011
    #4
  5. On 2011-02-10, Gordon Burditt <> wrote:
    >> Are there implementations in which argc can be 0 then?

    >
    > Yes. UNIX. Just have a program call, for example:
    >
    > execl(path, (char *) NULL);


    On most modern Unix systems that won't initialise main()'s argc to
    _anything_. Program invocation with a null argv is generally taken
    as an instruction to the dynamic linker. You'll get a listing of
    requested and linked in libraries and the program will terminate
    without ever calling main().

    --
    Andrew Smallshaw
    Andrew Smallshaw, Feb 12, 2011
    #5
  6. MartinBroadhurst

    Dr Nick Guest

    Andrew Smallshaw <> writes:

    > On 2011-02-10, Gordon Burditt <> wrote:
    >>> Are there implementations in which argc can be 0 then?

    >>
    >> Yes. UNIX. Just have a program call, for example:
    >>
    >> execl(path, (char *) NULL);


    That's gives me a warning about not enough variable arguments. execl
    needs a null terminated list and clearly the compiler "knows" to expect
    a real one in there.

    > On most modern Unix systems that won't initialise main()'s argc to
    > _anything_. Program invocation with a null argv is generally taken
    > as an instruction to the dynamic linker. You'll get a listing of
    > requested and linked in libraries and the program will terminate
    > without ever calling main().


    With an extra NULL, or with execv I get a segfault from:

    #include <unistd.h>

    int main(void) {
    execv("/bin/ls",(char * const *)NULL);
    /* or, and ignore the warning */
    execl("/bin/ls",(char *)NULL);
    /* or */
    execl("/bin/ls",(const *)NULL,(char *)NULL);
    return 0;
    }

    and debugging does seem to show it was in the dynamic linker.

    execl("/bin/ls","",(char * const *)NULL);
    works but, of course, has an argument.

    So I don't think it's as easy as we thought!
    --
    Online waterways route planner | http://canalplan.eu
    Plan trips, see photos, check facilities | http://canalplan.org.uk
    Dr Nick, Feb 12, 2011
    #6
  7. Dr Nick <> writes:

    > Andrew Smallshaw <> writes:
    >
    >> On 2011-02-10, Gordon Burditt <> wrote:
    >>>> Are there implementations in which argc can be 0 then?
    >>>
    >>> Yes. UNIX. Just have a program call, for example:
    >>>
    >>> execl(path, (char *) NULL);

    >
    > That's gives me a warning about not enough variable arguments. execl
    > needs a null terminated list and clearly the compiler "knows" to expect
    > a real one in there.
    >
    >> On most modern Unix systems that won't initialise main()'s argc to
    >> _anything_. Program invocation with a null argv is generally taken
    >> as an instruction to the dynamic linker. You'll get a listing of
    >> requested and linked in libraries and the program will terminate
    >> without ever calling main().

    >
    > With an extra NULL, or with execv I get a segfault from:
    >
    > #include <unistd.h>
    >
    > int main(void) {
    > execv("/bin/ls",(char * const *)NULL);
    > /* or, and ignore the warning */
    > execl("/bin/ls",(char *)NULL);
    > /* or */
    > execl("/bin/ls",(const *)NULL,(char *)NULL);
    > return 0;
    > }
    >
    > and debugging does seem to show it was in the dynamic linker.
    >
    > execl("/bin/ls","",(char * const *)NULL);
    > works but, of course, has an argument.
    >
    > So I don't think it's as easy as we thought!


    That depends on what you thought! Andrew is talking about a null argv
    and that's not the same as the original proposal of starting a program
    with argc == 0. When argc == 0, argv must have at least one element: a
    null pointer.

    You can do this:

    #include <unistd.h>

    int main(void)
    {
    char *argv[] = {0};
    execv("./args", argv);
    }

    and in when args is this program:

    #include <stdio.h>

    int main(int argc, char **argv)
    {
    printf("argc=%d argv[0]=%p\n", argc, (void *)argv[0]);
    return 0;
    }

    you get:

    $ ./exec
    argc=0 argv[0]=(nil)

    which is answers the question at the top of this post.

    --
    Ben.
    Ben Bacarisse, Feb 13, 2011
    #7
    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. Vinu
    Replies:
    9
    Views:
    615
  2. Vinu
    Replies:
    4
    Views:
    4,792
    Ron Natalie
    May 10, 2005
  3. Hal Styli
    Replies:
    14
    Views:
    1,625
    Old Wolf
    Jan 20, 2004
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,804
    Smokey Grindel
    Dec 2, 2006
  5. significantBit

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

    significantBit, Apr 9, 2008, in forum: C Programming
    Replies:
    2
    Views:
    1,719
    John Bode
    Apr 9, 2008
Loading...

Share This Page