Why do we need argc while there is always a null at the end of argv?

C++CMain

C++ Problem Overview


It seems that the argv[argc] is always NULL, so I think we can traverse the argument list without argc. A single while loop will do this.

If there is always a NULL at the end of argv, why do we need an argc?

C++ Solutions


Solution 1 - C++

Yes, argv[argc]==NULL is guaranteed. See C11 5.1.2.2.1 Program startup (my emphasis)

> If they are declared, the parameters to the main function shall obey > the following constraints: > > The value of argc shall be nonnegative. > argv[argc] shall be a null > pointer.

Providing argc therefore isn't vital but is still useful. Amongst other things, it allows for quick checking that the correct number of arguments has been passed.

Edit: The question has been amended to include C++. n3337 draft 3.6.1 Main function says

> 2 ...argc shall be the number of arguments passed to the program from > the environment in which the program is run. .... The value of argc > shall be non-negative. The value of argv[argc] shall be 0.

Solution 2 - C++

Yes, argv[argc] is guaranteed to be a null pointer. argc is used for convenience.

Quoting the official explanation from C99 Rationale, note the words redundant check:

>### Rationale for International Standard — Programming Languages — C §5.1.2.2.1 Program startup > >The specification of argc and argv as arguments to main recognizes extensive prior practice. argv[argc] is required to be a null pointer to provide a redundant check for the end of the list, also on the basis of common practice.

Solution 3 - C++

It's for historical reasons, and compatibility with old code. Originally, there was not a guarantee that there would exist a null pointer as the last element of the argv array. But argc has always existed.

Solution 4 - C++

We "need" it, because it's required by various standards.

We are free to ignore the value completely, but since it is first parameter of main, we must have it in parameter list. In C++ (and probably non-standard C dialects), you can just omit the parameter name, like this C++ snippet (easy to convert to C):

#include <stdio.h> // C-compatible include, guarantees puts in global namespace

// program will print contents of argv, one item per line, starting from argv[0]

int main(int /*argc*/, char *argv[]) { // uncomment argc for C

    //(void)argc; // uncomment statement for C

    for (int i=0; argv[i]; ++i) {
        puts(argv[i]);
    }

    return 0;
}

In standard C, with common warnings settings, unused parameter generates warning, which can be fixed by a statement like (void)argc; which causes the name to be used without generating any code.

argc is nice to have, because otherwise many programs would need to walk thorugh the parameters to get the count. Also, in many programming languages with arrays that have length, there isn't any argc parameter, there's just an array with the items.

Solution 5 - C++

  • In the event one requires to access the last argument from a list of inputs it is more convenient to use argv[argc - 1] rather than looping.
  • It is better (cleaner) to have argc provided to me rather than having to write code that will give me the count separately when the logic requires me to (and there are cases where this can happen).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStarPinkERView Question on Stackoverflow
Solution 1 - C++simoncView Answer on Stackoverflow
Solution 2 - C++Yu HaoView Answer on Stackoverflow
Solution 3 - C++zentrunixView Answer on Stackoverflow
Solution 4 - C++hydeView Answer on Stackoverflow
Solution 5 - C++AregawiView Answer on Stackoverflow