"error: assignment to expression with array type error" when I assign a struct field (C)

CArraysStringStructInitialization

C Problem Overview


I'm a beginner C programmer, yesterday I learned the use of C structs and the possible application of these ones about the resolution of specific problems. However when I was experimenting with my C IDE (Codeblocks 16.01) in order to learn this aspect of C programming, I've encountered a strange issue. The code is the following:

#include <stdio.h>

#define N 30

typedef struct{
     char name[N];
     char surname[N];
     int age;
} data;

int main() {
     data s1;
     s1.name="Paolo";
     s1.surname = "Rossi";
     s1.age = 19;
     getchar();
     return 0;
}

During the compilation, the compiler (GCC 4.9.3-1 under Windows) reported me an error that says

> "error: assignment to expression with array type error"

on instruction

s1.name="Paolo" 
s1.surname="Rossi" 

while if I do

data s1 = {"Paolo", "Rossi", 19};

it works. What am I doing wrong?

C Solutions


Solution 1 - C

You are facing issue in

 s1.name="Paolo";

because, in the LHS, you're using an array type, which is not assignable.

To elaborate, from C11, chapter §6.5.16

> assignment operator shall have a modifiable lvalue as its left operand.

and, regarding the modifiable lvalue, from chapter §6.3.2.1

> A modifiable lvalue is an lvalue that does not have array type, [...]

You need to use strcpy() to copy into the array.

That said, data s1 = {"Paolo", "Rossi", 19}; works fine, because this is not a direct assignment involving assignment operator. There we're using a brace-enclosed initializer list to provide the initial values of the object. That follows the law of initialization, as mentioned in chapter §6.7.9

> Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.[....]

Solution 2 - C

typedef struct{
     char name[30];
     char surname[30];
     int age;
} data;

defines that data should be a block of memory that fits 60 chars plus 4 for the int (see note)

[----------------------------,------------------------------,----]
 ^ this is name              ^ this is surname              ^ this is age

This allocates the memory on the stack.

data s1;

Assignments just copies numbers, sometimes pointers.

This fails

s1.name = "Paulo";

because the compiler knows that s1.name is the start of a struct 64 bytes long, and "Paulo" is a char[] 6 bytes long (6 because of the trailing \0 in C strings)
Thus, trying to assign a pointer to a string into a string.

To copy "Paulo" into the struct at the point name and "Rossi" into the struct at point surname.

memcpy(s1.name,    "Paulo", 6);
memcpy(s1.surname, "Rossi", 6);
s1.age = 1;

You end up with

[Paulo0----------------------,Rossi0-------------------------,0001]

strcpy does the same thing but it knows about \0 termination so does not need the length hardcoded.

Alternatively you can define a struct which points to char arrays of any length.

typedef struct {
  char *name;
  char *surname;
  int age;
} data;

This will create

[----,----,----]

This will now work because you are filling the struct with pointers.

s1.name = "Paulo";
s1.surname = "Rossi";
s1.age = 1;

Something like this

[---4,--10,---1]

Where 4 and 10 are pointers.

Note: the ints and pointers can be different sizes, the sizes 4 above are 32bit as an example.

Solution 3 - C

Please check this example here: Accessing Structure Members

There is explained that the right way to do it is like this:

strcpy(s1.name , "Egzona");
printf( "Name : %s\n", s1.name);

Solution 4 - C

Use strcpy() function for modifying the value. Because directly assigning value to a string is not possible in C.(Not Assignable error will show).

strcpy(s1.name, "New_Name");

Solution 5 - C

you get error because you are trying to change a constant. when we initialize a string like char sample[20]; , the sample itself is a constant pointer which means you can change the value of the thing that pointer is pointing to, but you can't change the value of the pointer itself! when you initialize char sample it is like sample as a pointer is initialized aschar* const sample; and when you try to do this:s1.name="paulo"; you are actually trying to change the strings address. in fact when you compile and run your program the string "paulo" fills part of your memory independent of s1.name. to understand better you can run the following code : #include <stdio.h> int main() { char name[20]; printf("address of sample:%d address of a random string:%d",name,"paolo"); } the output will give you two independent addresses like X and Y. X is the address of s1.name and Y is the address of paulo. you can't change X to Y since it is a constant.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionp4nzer96View Question on Stackoverflow
Solution 1 - CSourav GhoshView Answer on Stackoverflow
Solution 2 - CteknopaulView Answer on Stackoverflow
Solution 3 - Cuser5308956View Answer on Stackoverflow
Solution 4 - CAkash RoyView Answer on Stackoverflow
Solution 5 - CVindictiveView Answer on Stackoverflow