Reputation: 229
I've just started learning C with a professional Java background and some (if no too much) C++ knowledge, and I was astonished that this doesn't work in C:
struct Point {
int x;
int y;
};
Point p;
p.x = 0;
p.y = 0;
It seems that I have to declare p
using struct Point
as the type or using a typedef
. Does this code works in C99? Or is this a "C++ thing"?
Upvotes: 4
Views: 3003
Reputation: 32533
Structs are not types. You can create a point from a struct as follows:
struct Point p;
p.x = 0;
p.y = 0;
If you want to use a struct as a type, you have to typedef it. This works in both C and C++:
typedef struct _point {
int x;
int y;
} Point;
Always give your struct a name though, if you have to forward declare it to be able to have pointers to a struct of the same type or circular dependencies.
Upvotes: 1
Reputation: 146053
So...
Point a tag
struct Point a type
typedef struct {
. . .
} Point_t;
Point_t a type
I often see a why? written between the lines. After all, it does seem perfectly reasonable to just say Point x;
, so why can't you?
As it happens, early implementations of C established a separate name space for tags vs other identifiers.There are actually 4 name spaces1. Once the language was defined this way, it was then not possible to allow the struct tag to be used as a type because then all existing code with name collisions between ordinary identifiers and tags would be suddenly in error.
1. The 4 name spaces are:
-- label names (disambiguated by the syntax of the label declaration and use);
-- the tags of structures, unions, and enumerations (disambiguated by following any) of the keywords struct, union, or enum);
-- the members of structures or unions; each structure or union has a separate name
space for its members (disambiguated by the type of the expression used to access the
member via the . or -> operator);
-- all other identifiers, called ordinary identifiers (declared in ordinary declarators or as
enumeration constants)
Upvotes: 2
Reputation: 49311
In C there is no confusion between
struct Point {
int x;
int y;
};
and
union Point {
int x;
int y;
};
which are two different types called struct Point
and union Point
respectively.
The C99 standard section 6.7.2.1 states:
6 Structure and union specifiers have the same form. The keywords
struct
andunion
indicate that the type being specified is, respectively, a structure type or a union type.7 The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type, within a translation unit.
So it most unequivocally declares a type. The syntax for type names in C is given in sections 6.7.6 and includes the specifier-qualifier-list from 6.7.2, which takes the form of struct-or-union identifier
.
Does this code works in C99? Or is this a "C++ thing"?
No, C99 does not decide to promote structure types over enum types and union types with the same name. It is a "C++ thing", as struct and classes are mostly the same thing in C++, and classes are important to C++.
Upvotes: 4
Reputation:
You first need to make Point a type like :
typedef struct Point {
int x;
int y;
} Point;
This allows you to use Point
as a type, or struct Point
I.e:
Point *p;
sizeof(struct Point);
Some people prefer to make the name of the structure different from the type being created, such as:
typedef struct _point {
...
} Point;
You'll run into both. The last example tells me that I should not use struct _point
, its not meant to be exposed except as the type Point
.
Upvotes: 0
Reputation: 238068
In C, structs can have two kinds of names: a tag name, and a type name. A tag name can only be used if it's prefixed with struct, like:
struct mytag { int a; }
struct mytag mystruct;
A typedef allows you to define both a tag name and a type name. The type name can be used without a struct prefix:
typedef struct mytag { int a; } mytype;
mytype mystruct; // No struct required
Upvotes: 1
Reputation: 59553
struct Point
is the type just like union Foo
would be a type. You can use typedef
to alias it to another name - typedef struct Point Point;
.
Upvotes: 4
Reputation: 16512
No, a struct do not define a new type. What you need is:
typedef struct {
int x; int y;
} Point;
Now Point is new type you can use:
Point p;
p.x = 0; p.y = 0;
Upvotes: 5
Reputation: 109012
It doesn't work in C99, it is a C++ thing. You have to either say struct Point
or use a typedef in C.
Upvotes: 1
Reputation: 9060
As far as I know, it shouldn't work without a typedef
in C99 either (as this is simply the way C works), but it does work in C++ as a struct
in C++ is just a class
with all members public by default.
Upvotes: 8
Reputation: 127428
That's the way C works. In C you have to say:
typedef struct Point {
int x;
int y;
} Point;
And then you'll have a type called Point
that does what you want.
In C++ it's enough to define it the way you did.
Upvotes: 0