Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 657
p4nzer96 Avatar asked May 14 '16 10:05

p4nzer96


2 Answers

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.[....]

like image 156
Sourav Ghosh Avatar answered Sep 19 '22 23:09

Sourav Ghosh


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.

like image 30
teknopaul Avatar answered Sep 20 '22 23:09

teknopaul