Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C (http://www.go4expert.com/forums/c/)
-   -   Commandline and Lvalue (http://www.go4expert.com/forums/commandline-and-lvalue-t11735/)

shyam_oec 30Jun2008 10:07

Commandline and Lvalue
 
void main(int argc,char *argv[])
{
printf("\n%c",++(*(++(*++argv))));
}


Running the executable file of this program at command line,with arguments 'PR5 aabbcc' gave output 's'.
can u explain how it worked.
I still have a doubt,that how it compiled well,since in statement '++argv',i think
compiler should have given Lvalue error,but it is running well!plese explain how?

xpi0t0s 16Jul2008 16:00

Re: Commandline and Lvalue
 
It's undefined, because you're using multiple operations with side effects in the same calculation. So anything could happen, including monkeys flying out of your nose.

When I ran it without parameters I got an access violation reading location 0x00000002. This should be a clue.
When I ran it with parameters PR5 aabbcc I got the output 6.
When I realised argv was _TCHAR *[] and changed it to char *[], I then got the output 'S' (although uppercase, not lowercase as in your example).
The expression argv[1][1]+1 evaluates to 'S', doesn't use side effects and is not undefined.

If you want to determine exactly what it's doing in your specific situation, for interest only rather than for use anywhere else, then run repeated tests building up the expression from the first operation and see what it displays each time. Don't forget to change the format string to match whatever it's doing. For example:
printf("%s\n",*++argv); // %s because *++argv is a string
printf("%s\n",++(*++argv)); // %s because a string pointer preincremented is still a string pointer
printf("%c\n",*(++(*++argv))); // %c because dereferencing a string pointer gives a character
...and so on.

Compiler implementors are free to determine when they apply side effects, which is why the behaviour is undefined. Taking a simpler example i++ + i++, this may be implemented as equivalent to
i + (i+1); i+=2;, or
i+i; i+=2;, or
(i+1) + i; i+=2;
and possibly other ways. In the first case the postincrement happens immediately after the value of i is taken, and this happens as the expression is parsed from left to right. In the second case the two postincrements aren't applied until after the calculation is over. The third is the same as the first except that the expression is parsed from right to left. In the second the result of the addition is 2, but in the other two the result is 3.

So if you preincrement argv, dereference it and preincrement the result, then dereference and preincrement that, a number of different things could happen depending on what was on the compiler implentor's mind at the time. Try:

int main(int argc,char *argv[])
{
char **argv_reset=argv;
printf("(1) argv[0]=%s\natgv[1]=%s\nargv[2]=%s\n",argv[0],argv[1],argv[2]);
printf("%c\n",++(*(++(*++argv))));
printf("(2) argv[0]=%s\natgv[1]=%s\nargv[2]=%s\n",argv[0],argv[1],argv[2]);
argv=argv_reset;
printf("(3) argv[0]=%s\natgv[1]=%s\nargv[2]=%s\n",argv[0],argv[1],argv[2]);
}
and see what you get.

shabbir 16Jul2008 19:57

Re: Commandline and Lvalue
 
Very well explained xpi0t0s, Some Repu comes your way


All times are GMT +5.5. The time now is 19:17.