There are some problems with your code.
First, const char *x = "abc" will initialize x with a pointer value pointing sometimes in the read-only zone of executable, to trying to initialize by indirection so *x = something will segfault due to missing write-permission in that segment.
Next, x = malloc(0) -- this is a correct call and the only valid operation you can do with the returned pointer x is free(x) -- read the manpage of malloc.
If size is 0, then malloc() returns either NULL, or a unique pointer
value that can later be successfully passed to free()
Finally, your code is rewritten so -- supposing that you make x point in a writable zone.
void
foo()
{
char*a,*b;
a=calloc(100,1);
b=calloc(100,1);
memcpy(b,"",4);
printf("%p %p `%s `%s\n",a,b,a,b);
loop:
*a=*b;
if (!*b) goto end; /* sequence point after controlling expression of `while`*/
a=a+1;
b=b+1;
goto loop;
end:
a=a+1;
b=b+1;
printf("%p %p `%s `%s\n",a,b,a,b);
}
int
main()
{
char*a,*b;
a=calloc(100,1);
b=calloc(100,1);
memcpy(b,"",4);
printf("%p %p `%s `%s\n",a,b,a,b);
while(*a++=*b++);
printf("%p %p `%s `%s\n",a,b,a,b);
foo();
return 0;
}
Here the only trouble is the evaluation of the condition of while statement.
6.8.5.1 The while statement
1 The evaluation of the controlling expression takes place before each
execution of the loop body.