21

I was curious about why this is not allowed in C:

char myarray[4];

myarray = "abc";

And this is allowed:

char myarray[4] = "abc";

I know that in the first case I should use strcpy:

char myarray[4];

strcpy(myarray, "abc");

But why declaration and later initialization is not allowed and declaration and simultaneous initialization is allowed? Does it relate to memory mapping of C programs?

Thanks!

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
Alexey Pimenov
  • 213
  • 1
  • 2
  • 4

5 Answers5

40

That's because your first code snippet is not performing initialization, but assignment:

char myarray[4] = "abc";  // Initialization.

myarray = "abc";          // Assignment.

And arrays are not directly assignable in C.

The name myarray actually resolves to the address of its first element (&myarray[0]), which is not an lvalue, and as such cannot be the target of an assignment.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • `&myarray[0]` is not an lvalue? But I thought an lvalue was just a memory location. The problem in this case is `myarray` is *const*, not that it is not an lvalue. – Big McLargeHuge Dec 10 '15 at 21:39
  • 1
    @Dave, an lvalue is a "memory location", and that's why `&myarray[0]` is not an lvalue -- it's an address, not the memory location it points to. – Frédéric Hamidi Dec 11 '15 at 07:38
4

Yes, this is a kind of inconsistency in the language.

The "=" in myarray = "abc"; is assignment (which won't work as the array is basically a kind of constant pointer), whereas in char myarray[4] = "abc"; it's an initialization of the array. There's no way for "late initialization".

You should just remember this rule.

Vlad
  • 35,022
  • 6
  • 77
  • 199
  • 3
    There is no inconsistency at that point. `marray` is an array and not a pointer, that's all. – Jens Gustedt Feb 12 '11 at 13:38
  • 1
    @Jens: the inconsistency is in the fact that the initialization is denoted syntactically the same way as the assignment. This is exactly what led to the misunderstanding. – Vlad Feb 13 '11 at 11:18
  • That syntax there is only a shortcut. I think that `char myarray[4] = { "abc" };` makes things much clearer and unambiguous. – Jens Gustedt Feb 13 '11 at 13:02
  • 1
    @Jens: the syntax you mention in the last comment differs from the one which OP is discussing. This syntax would be of course less ambiguous. In my opinion, having initialization and assignment visually different should be a good hint to the developers that they are not the same. The syntax could be perhaps `char myarray[4]("abc");` or something like that. – Vlad Feb 13 '11 at 13:08
1
myarray = "abc";

...is the assignation of a pointer on "abc" to the pointer myarray.

This is NOT filling the myarray buffer with "abc".

If you want to fill the myarray buffer manually, without strcpy(), you can use:

myarray[0] = 'a', myarray[1] = 'b', myarray[2] = 'c', myarray[3] = 0;

or

char *ptr = myarray;
*ptr++ = 'a', *ptr++ = 'b', *ptr++ = 'c', *ptr = 0;

Your question is about the difference between a pointer and a buffer (an array). I hope you now understand how C addresses each kind.

YasirA
  • 9,531
  • 2
  • 40
  • 61
pierre
  • 11
  • 1
1

This is another C example of where the same syntax has different meanings (in different places). While one might be able to argue that the syntax should be different for these two cases, it is what it is. The idea is that not that it is "not allowed" but that the second thing means something different (it means "pointer assignment").

davep
  • 90
  • 2
0

I think these are two really different cases. In the first case memory is allocated and initialized in compile-time. In the second - in runtime.

Nofate
  • 2,714
  • 3
  • 32
  • 32