-6

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?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Ananya
  • 35
  • 1
  • 6
  • 4
    [Did you try it ? What result did you get ?](http://ideone.com/ZF08IY) – Paul R Apr 20 '17 at 11:07
  • 1
    In the code shown `char *argv[]` is exactly 100% the same as `char **argv`. I like the last format better: there is no array anywhere. You might like to read section 6 of the [c-faq](http://c-faq.com/). – pmg Apr 20 '17 at 11:09
  • @pmg: each to their own, but I tend to think of `char *argv[]` as an array of `char *`, i.e. an array of strings. – Paul R Apr 20 '17 at 11:10
  • @PaulR: you can't `++` an array. – pmg Apr 20 '17 at 11:12
  • 1
    @pmg: true - I guess I make a mental distinction between a *conceptual* array (in this case a contiguous sequence of pointers) and an array in the strict "C language lawyer" sense. – Paul R Apr 20 '17 at 11:13
  • @Paul what is ./prog in output? – Ananya Apr 20 '17 at 11:17
  • Why isit not showing compile time error? – Ananya Apr 20 '17 at 11:18
  • 1
    @Ananya: `./prog` is the first part of the command line - usually the name used to invoke the program (but not necessarily). In this case it's just running a program called `prog` with no further command line arguments. There is no compile error because there is nothing wrong with the code. – Paul R Apr 20 '17 at 11:32
  • @Paul But post or preincrement should not do in base address of an array right? – Ananya Apr 20 '17 at 11:39
  • Why is it showing the program name? – Ananya Apr 20 '17 at 11:43
  • 1
    @Ananya: did you *read* any of the answers and comments below ? `argv[]` contains the program name (in element 0) and any command line arguments (in elements 1..argc-1). – Paul R Apr 20 '17 at 11:52
  • yes, thank u for clearence.:) – Ananya Apr 20 '17 at 12:19

1 Answers1

4

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.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • You might also want to explain that although the command line parameter is `char *argv[]`, this decays to `char **argv` within the function, which makes it legal to increment `argv`, i.e. `argv++` - I think this may be one of the things that is confusing the OP. – Paul R Apr 20 '17 at 11:35
  • @PaulR I think I finally got it better, can you please review sir? – Sourav Ghosh Apr 20 '17 at 13:02