Question

Given a pointer and an array, setting one equal to another fails in one case, and works in another.

char *c_ptr = "I'm a char pointer";
char c_arry[] = "I'm a char array";
c_ptr = c_arry;  //This line works.
c_arry = c_ptr;  //This line fails.

When the line above fails, it generates this warning: "error: incompatible types when assigning to type". This error seems disingenuous, and frankly, a little slutty, given that just a line prior, she claimed she was my type.

Trying to understand this issue, I re-read K&R's chapter on pointers and arrays and noticed on page 102 their claim that "the array name is the address of the zeroth element". If K&R is accurate, substituting in &c_arry[0] should generate the same error, right? But this line:

&c_arry[0] = c_ptr;

gives me a new error: "lvalue required as left operand of assignment". Why does this so-called identical value generate a different error? When GCC and K&R contradict each another, that's when I turn to the experts on stackoverflow.

Reading up a bit on l-values, I've come to the conclusion that this is an L-value vs. R-value issue, and that c_arry can only be an L-value - that is, an assigned value - in two, and only two situations:

  • String initialization (i.e. char c_arry[] = "I'm a char array"; )
  • and character assignment (i.e. c_arry[0] = 'A'; )

Is my conclusion accurate? Are these the only two ways that c_arry can ever be assigned?

Or put another way, is there ever an X, for any of the following lines of code, that is ever valid?

c_arry     = X;
&c_arry    = X;
&c_arry[0] = X;
*c_arry    = X;
*c_arry[0] = X;
Was it helpful?

Solution

The fact that "the array name is the address of the zeroth element" is true most of the time1 does not mean that you can assign it anything. Although this

char str[] = "hello";

looks like an assignment, it is in fact initialization; the concept of lvalue does not apply to it.

Moreover, obtaining an address using & operator never produces an lvalue, so there is no way to come up with an X that does not break your first three examples.

The last two, however, can be assigned, with some minor tweaks:

*c_arry = 'x';           // the same as c_arry[0] = 'x'
char *c_arry_of_ptr[2];
...
*c_arry_of_ptr[0] = 'x';


1 One notable exception is sizeof(c_arry) - here, it's not the same as sizeof(&c_arry[0]) for arrays of size other than 1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top