Reputation: 1
list.h: In function ‘CreateNewLinks’:
list.h:29:20: warning: assignment to ‘numbers *’ from incompatible pointer type ‘struct numbers *’ [-Wincompatible-pointer-types]
29 | linked = linked->NextNum;
typedef struct{
int num;
struct numbers *NextNum;
}numbers;
numbers *CreateNewLinks(){
numbers *head=NULL;
head=malloc(sizeof(numbers));
numbers* linked = head;
char answer;
do{
printf("Enter number : ");
scanf("%d",&linked->num);
printf("Do you want to add (y/n) : ");
scanf("%c",&answer);
if(answer == 'y' || answer == 'Y'){
linked->NextNum = malloc(sizeof(numbers));
linked = linked->NextNum;
}else
linked->NextNum = NULL;
}while(answer =='y' || answer == 'Y');
return head;
}
How can this problem be solved?
Upvotes: -1
Views: 93
Reputation: 311078
In this typedef declaration
typedef struct{
int num;
struct numbers *NextNum;
}numbers;
there are declared two different type specifiers. The first one is the unnamed structure of complete type alias of which is numbers
. The second one is the incomplete structure type struct numbers
. That is there are two type specifiers numbers
and struct numbers
. They are different types and as a result are incompatible and hence pointers to objects of these types are also incompatible.
You need to introduce a structure tag as for example
typedef struct numbers{
int num;
struct numbers *NextNum;
}numbers;
or
typedef struct numbers numbers;
struct numbers{
int num;
numbers *NextNum;
};
There is one more problem with your function. The format string in this call of scanf
scanf("%c",&answer);
should have a leading space like
scanf(" %c",&answer);
^^^
It allows to skip white space characters. Otherwise your call of scanf
will also read for example the new line character '\n'
that is placed in the buffer after pressing the Enter key in the preceding call of scanf
scanf("%d",&linked->num);
Also you need to check whether memory was successfully allocated in calls of malloc
.
Pay attention to that the function should do only one task. This do-while loop
do{
printf("Enter number : ");
scanf("%d",&linked->num);
//...
}while(answer =='y' || answer == 'Y');
should be moved from the function in main. That is you need to write a function that appends only one node to the list and will be called from a loop similar to shown above.
Upvotes: 2
Reputation: 7345
typedef struct{
int num;
struct numbers *NextNum;
}numbers;
Let's break these into two separate operations:
struct {
int num;
struct numbers *NextNum;
};
// And now the typedef.
Do you see the missing tag? struct numbers
was never defined. It should be:
struct numbers {
int num;
struct numbers *NextNum;
}
And now you can define an alias for struct numbers
:
typedef struct numbers numbers;
Or do it like you were originally trying to:
typedef struct numbers {
int num;
struct numbers *NextNum;
} numbers;
Upvotes: 2
Reputation: 24062
You never defined struct numbers
, so when it sees it, it assumes it's some distinct type from the numbers
type. You can fix it by adding the missing tag to the typedef
:
typedef struct numbers {
int num;
struct numbers *NextNum;
} numbers;
If you'd rather use numbers
inside the structure as well, you can instead do:
typedef struct numbers *numbers;
struct numbers {
int num;
numbers *NextNum;
};
This is a fairly common idiom.
Upvotes: 3
Reputation: 223663
First you give the structure a tag:
struct numbers
Then you define the structure using that tag:
struct numbers {
int num;
struct numbers *NextNum;
};
Then you give the structure type a name:
typedef struct numbers {
int num;
struct numbers *NextNum;
} numbers;
In your original code, where you have struct numbers *NextNum;
, there is no declaration of the tag numbers
yet. So the compiler takes struct numbers
to refer to some type it does not yet have a definition for.
The code typedef struct{
starts the definition of a structure type with no tag. The code struct numbers
will never refer to this structure type, because a structure type with no tag and a structure type with a tag will never be the same type.
The code typedef struct{…}numbers;
gives the structure type a name, numbers
. But a name is not a tag. The name numbers
by itself will refer to the structure type, but it refers to the structure with no tag. It does not refer to the structure type with a tag, struct numbers
. numbers
and struct numbers
are different types. (This is different from C++, where structure, union, and class tags are automatically names of the types.)
In linked = linked->NextNum;
, linked->NextNum
is a pointer to struct numbers
, but linked
is a pointer to numbers
. Since these are different types, and the assignment between them is inappropriate, the compiler warns you. Changing the structure definition as shown above will resolve this.
Upvotes: 3