#include <stdio.h>
void main(void)
^^^^^^^^^^^^^^^^
This way of declaring the main function doesn't conform to ISO C, which
specifies the behavior only for these two portable forms.
int main(void)
int main(int, char **);
Implementations can support additional forms of the startup function.
(Did you read in your toolchain documentation that void main(void)
is supported? Even if so, there isn't a good reason to write
that way.)
printf("%c,%c,%c,%c",*p,*(++p),*(p++),*p);
Here, a function is called with five arguments:
printf(arg1, arg2, arg3, arg4, arg5);
These argument values are obtained, prior to the function call, by evaluating
five argument expressions:
"%c,%c,%c,%c" -> arg1
*p -> arg2
*(++p) -> arg3
*(p++) -> arg3
*p -> arg4
(Actually, six expressions are evaluated in an unspecified order:
the printf identifier is also an expression: a function designator).
Now here is the kicker. The ISO C standard says that the order
of evaluation of these expressions is "unspecified".
In other words, evaluation does not necessarily go in the order
arg1, arg2, arg3 ... It could be in any order, including, possibly,
interleaved orders.
That's what the behavior would be with a compiler that generates code which
evaluates function arguments strictly left to right (and completely so, to the
point of settling all the side effects of one expression before moving on to
the next one: in other words, imposing a "sequence point".)
However, there is no such requirement.
The following function call to f can invoke the functions a, b and c in any of
the six possible orders:
f(a(), b(), c());
other than that, it is well-defined, because function calls are sequenced in C:
the execution of function calls cannot overlap. A sequence point occurs
before a function is called and when it returns.
In your case, the behavior is undefined because you have side effects
in your expressions (incrementing the pointer p).
In C, if an object is modified twice without a sequence point in between,
it is undefined behavior.
Somewhat confusingly, the C comma operator does impose a sequence point, and
strict left to right evaluation. So this kind of thing is well-defined:
char *q = (p++, p++, p++);
The comma which separates function argument expressions, however, does not
impose a sequence point or ordering, so the following type of thing is not well-defined:
f(p++, p++, p++);
Not well-defined means that the C standard doesn't provide a requirement
as to what the behavior should be; it is entirely in the hands of the
implementation.
one more situation:
#include <stdio.h>
void main(void)
char p[] ="sahil"; <<<< Change in the declaration
p is now the name of an array, and not a pointer.
printf("%c,%c,%c,%c",*p,*(++p),*(p++),*p); <<<<Line 7
Here, you're trying to increment an array.
The standard calls this situation a "constraint violation", which requires a
diagnostic.
The ++ operator can only be applied to lvalues which are integers,
floating-pointers numbers or pointers.
Maybe in some future version of standard C, ++p will mean "increment every
element of the array p", or something else.