The following code compiles fine.
header.h:
typedef struct Placeholder_Type* Placeholder;
impl.cpp:
#include "header.h"
void doSomething(Placeholder t) {
(void) t;
}
int main() {
int *a = new int();
doSomething((Placeholder)a);
}
compilation command:
clang++ impl.cpp
The type Placeholder_Type does not exist anywhere and it doesn't exist as a symbol in the output binary.
Why is it legal to create a typedef for a type that does not exist?
Why can I create a function using a type that doesn't exist?
Is this equivalent to just using void* but named "Placeholder"?
struct Placeholder_Type
declares the struct Placeholder_Type
(but doesn't define it), no matter where it appears. Even if it's inside a typedef
. So you don't create a typedef to a struct that doesn't exist, but to one you just declared (and thus created, if the compiler didn't already know about it).
As for why, it's because this way you can keep the definition of a struct away from the public interface. For example, this is a typical way to implement an opaque object in C:
// mytype.h
typedef struct MytypeImpl* Mytype;
Mytype create_mytype();
void destroy_mytype(Mytype o);
void do_something_with_mytype(Mytype o, int i);
// mytype.c
struct MytypeImpl {
int something;
int otherthing;
};
Mytype create_mytype() {
Mytype o = malloc(sizeof(*o));
o->something = 0;
o->otherthing = 0;
return o;
}
void destroy_mytype(Mytype o) {
free(o);
}
// etc.
Individual styles may differ in details, of course. But the key point is that the definition of the struct isn't visible outside mytype.c, so nobody can just access the data members.