Search code examples
ccommand-line-argumentsargvargc

What is the output of this C code (run without any command line arguments)?


What is the output of this C code (run without any command line arguments)?

#include <stdio.h>
int main(int argc, char *argv[])
 {
    while (*argv  !=  NULL)
    printf("%s\n", *(argv++));
     return 0;
}

In this program argv gives the base address of array of char pointer so

while(*argv !=NULL) 

condition is true and this should give the compile time error because of *(argv++), is not it? But it is showing some output why?


Solution

  • Quoting shamelessly from the C11 spec, chapter §5.1.2.2.1, (emphasis mine)

    — The value of argc shall be non-negative.

    argv[argc] shall be a null pointer.

    — If the value of argc is greater than zero, the array members argv[0]through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.

    — If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.

    The snippet above is to simply print the supplied program parameters.

    • *argv != NULL is to check that we did not reach the end of argv array.
    • printf("%s\n", *(argv++)); , let's break it down,

      printf("%s\n", *argv));  //print the string pointed to by `argv`
      argv++;                  //increment argv to point to the next string 
      

    Now, coming to the question in "title"

    [...] (run without any command line arguments)?

    well, in that case, the argc has a value of 1, and only argv[0] hold a pointer to a string containing the program name. argv[1] points to NULL (or similar null pointer).

    So, in the loop

    • First condition check is success (*argv == argv[0] which is not NULL), it prints the program name
    • argv is incremented as a side effect of the post-increment.
    • Second iteration, *argv is the same as argv[1] now, which is NULL, condition is false, and it hits the final return statement.

    The question in the body

    this should give the compile time error because of *(argv++), is not it?

    No, it is not. Quoting chapter §6.7.6.3

    A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. [...]

    Hence, argv is a modifiable lvalue and can be used as the operand for postfix increment operator here.