Pioneerhfy
Pioneerhfy

Reputation: 21

C error: request for member error when i compile

I've got many error my first compile in C. I'm new in C programming. How can i solve this problem and why this happened?

My source code:

#include <stdio.h>
#include <stdlib.h>

struct n{
    int x;
    n *next;
};
typedef n node;

int main(){
    node *root;
    root = (node *)malloc(sizeof(node));
    root->x = 10;
    root->next = (node *)malloc(sizeof(node));
    root->next->x = 20;
    printf("%d", root->next->x);
    node *iter;
    iter = root;
    return 0;

}

And I've got these errors when i compile my code 'gcc LinkedList1.c -o LinkedList1;

LinkedList1.c:13:9: error: request for member ‘x’ in something not a structure or union
     root->x = 10;
         ^
LinkedList1.c:14:9: error: request for member ‘next’ in something not a structure or union
     root->next = (node *)malloc(sizeof(node));
         ^
LinkedList1.c:15:9: error: request for member ‘next’ in something not a structure or union
     root->next->x = 20;
         ^
LinkedList1.c:16:22: error: request for member ‘next’ in something not a structure or union
     printf("%d", root->next->x);

But there is no problem when i compile with g++

Upvotes: 1

Views: 123

Answers (4)

Stephan Lechner
Stephan Lechner

Reputation: 35154

C and C++ differ in the meaning of a struct-definition in the aspect that C++ automatically introduces a new type name named after the class/struct/union, whereas C does NOT introduce such a type name automatically. Confer, for example, this online C++ draft standard:

9. Classes

(1) A class is a type. Its name becomes a class-name within its scope.

(2) A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself. ...

So in C++, struct n { n *next }; introduces a new type named n, which is immediately available even in the struct-definition at hand, such that n *next already refers to an existing type. (Note that a struct and a class in C++ are almost identical).

The C-standard is not that clear in describing which part of the specification actually is the type name (cf, for example, this online C draft standard):

6.7.2.1 Structure and union specifiers

(7) ... The keywords struct and union indicate that the type being specified is, respectively, a structure type or a union type.

(8) The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type, within a translation unit. ... The type is incomplete until immediately after the } that terminates the list, and complete thereafter.

But actually struct n { ....} introduces a new type that is identified through keyword struct and the name n, i.e. through struct n.

Side note: An interesting/funny thing might be that even a reference to struct n in the structure definition at first hand refers to an incomplete type, i.e. struct n is a forward declaration right until the enclosing }. Only together with the definition of forward declarations for structs, which have been introduced to allow circular references between structs, a struct n *next becomes valid.

It is common practice then to "manually" introduce an alias by the means of a typedef, i.e. typedef struct n node, such that node alone has the same meaning as struct n. And often the alias is defined together with the structure itself. So your code for C could work as follows:

typedef struct n{
    int x;
    struct n *next;
} node;

Upvotes: 2

sg7
sg7

Reputation: 6298

// This compiles as a C program and gives value 20 as the output:

#include <stdio.h>
#include <stdlib.h>


struct node {
  int x;
  struct node *next;
};

int main()
{
    struct node *root;

    root = (struct node *) malloc(sizeof(struct node));
    root->x = 10;
    root->next = (struct node *) malloc(sizeof(struct node));
    root->next->x = 20;
    printf("%d", root->next->x);
    struct node *iter;
    iter = root;
}

C language requires struct keyword when referring to a struct variable.

Upvotes: 0

user7860670
user7860670

Reputation: 37468

In C to when you want to use a struct type prepending struct to type name is mandatory. A common practice is to define a type alias for structs in order to avoid doing this all the time. So your code should look like this:

struct n{
    int        x;
    struct n * next;
};
typedef struct n node;

In C++ there is no need to prepend struct all the time (or define extra type aliases) so the same code compiles fine with g++.

Upvotes: 1

gsamaras
gsamaras

Reputation: 73366

Change your struct definition to:

struct n {
    int x;
    struct n *next;
};
typedef struct n node;

where I prepended struct keyword before n. You have to do that, but you are probably confused with C++, which doesn't require you to do so.

Upvotes: 0

Related Questions