In C, as in physics, a scalar type is a type that just has a single magnitude. Integer types, floating point types and pointer types are considered to be scalar types. struct
s are not scalar types.
This line
a->p=(struct x)malloc(sizeof(struct x));
attempts to cast the result of a malloc which is a pointer (a void*
in fact and thus a scalar, to a struct which is not. a->p
is also a pointer, having type struct s*
so what the error message means is that your cast forgets the *
that makes the target type a pointer type. i.e. this is what it should be:
a->p=(struct x*)malloc(sizeof(struct x));
Actually, in C, as opposed to C++ you don't need to cast void*
to other pointer types, so it is better just to write
a->p=malloc(sizeof(struct x));
The main reason for this is that if you forget to include stdlib.h
which is where the prototype for malloc
comes from, the compiler assumes that malloc
returns int
which is a disaster if a pointer cannot be represented as an int
. For example, modern 64 bit compilers often have 32 bit int
and 64 bit pointers. Putting the cast in silences the warning that the compiler is assuming malloc
returns int
because you forgot stdlib.h
One final improvement: you can take sizeof
of an object even if it doesn't exist yet so
a->p=malloc(sizeof *(a->p));
The compiler often knows the size of the thing a->p points to and so sets the sizeof to the right number as long as it knows the size (see "incomplete types" for an exception). Now you can modify the type of a->p
without having to fix all the malloc
s.