Reputation: 13947
/* Forward declare a type "point" to be a struct. */
typedef struct point point;
/* Declare the struct with integer members x, y */
struct point {
int x;
int y;
};
can you explain the reason behind forward declaring ?
Upvotes: 3
Views: 293
Reputation: 660297
I notice that no one has actually answered the question you asked, which was
What is the reason for forward-declaring a type?
The answer is: C was designed so that it could be compiled by reading each file once going from top to bottom. Consider a language like C#:
class C
{
B b;
}
class B
{
C c;
}
Notice that if the compiler is going from top to bottom, the compiler gets to a field of type B
before it knows what B
is. And in fact the C# compiler does not read the entire file once going from top to bottom. It makes many passes over each file, building up information as it goes.
Now suppose you wanted to write a C# compiler that could parse the program above without doing multiple passes. Somehow you'd have to tell the compiler before it encountered field b
that there was a type called B
. But we can't just move class B
to before class C
because that would create the same problem again, this time with C
!
In our imaginary one-pass version of C# you might say that you can get around the problem like this:
class B; // Tell the compiler that B will be defined later.
class C
{
B b;
}
class B
{
C c;
}
And there you go. When the compiler gets to B b
it knows that B
is a class that will be defined later. B
has been forward-declared.
Since C# has always used a multi-pass approach it does not need this trick. But the designers of C did want a single-pass approach, and so they require the redundancy of a forward declare.
This single-pass approach was designed to make compilation easier back in the day when machines had a few K of memory and ran at a few thousand cycles per second; C#'s approach of multiple scans building up complex data structures each time is expensive in comparison, and would be difficult on a machine with constrained speed and memory.
Now of course we have machines with trillions of bytes of memory (remember, memory is disk space; RAM is just a cache over disk!) that run billions of cycles per second, and yet still we are stuck with having to use techniques to make compiler writer's lives easier back in the 1970s. That's how it goes when you use C.
Upvotes: 11
Reputation: 5369
The purpose of typedef is to form complex types from more-basic machine types and assign simpler names to such combinations. They are most often used when a standard declaration is cumbersome, potentially confusing, or likely to vary from one implementation to another.
So typedef struct point point;
is not a forward declaration which you assume. It names struct point
to be point
, so that whenever you write point
later, it will refer to struct point
.
So now, you can declare a variable as point p;
rather than struct point p;
.
Upvotes: 2
Reputation: 41036
typedef struct point point;
struct point {
int x;
int y;
point *next; /* Could be used */
};
vs
// typedef struct point point;
struct point {
int x;
int y;
point *next; /* error: unknown type name ‘point’ */
};
Upvotes: 2
Reputation: 726809
This is not a forward declaration of a point
, this is a typedef
for it *. The typedef
lets you write
point p;
instead of
struct point p;
The forward declaration effect is not used in your code. However, with the typedef
in place you could start using point
as a type name, rather than a struct
tag, inside the declaration of the point
structure.
A more common way of achieving the same effect is to combine the definition and the typedef
, like this:
typedef struct point {
int x;
int y;
} point;
* The typedef
happens to forward-declare the type, but that is a "side effect".
Upvotes: 1