I want to forward-declare the parts of a struct, so the "package" struct is first shown. I'm getting an error of "use of undefined struct" where "Header" is declared in "Package". Surely the compiler (VS2010) would scan the header file for the definition before throwing this error?
struct Header;
struct Package
{
Header header; <-- "uses undefined struct"
};
struct Header
{
uint32_t Signature;
uint8_t MajorVersion;
uint8_t MinorVersion;
};
Thanks
I'm getting an error of "use of undefined struct" where "Header" is declared in "Package".
You can't declare a member of an incomplete type, because the compiler doesn't know how big it is and how much space should it reserve for it (among other things).
Surely the compiler (VS2010) would scan the header file for the definition before throwing this error?
No, what makes you think that?
You can't have Package contain something of type Header when the compiler doesn't yet know what exactly Header is. You can only have pointers to Header.
You cannot use the type until it has been fully declared, since information such as the size etc. needs to be known beforehand. You can, however, make pointers to these types, since they do not require this information.
There are two ways to resolve this. A cheaty one and a "proper" one.
First the cheaty one. You can prototype a struct, however, you can only use the struct as a pointer until you declare it. So you cannot use Header
as a value type before it has been declared. So the cheaty way would be replacing Header header;
with Header *header;
and then allocate memory at runtime.
There is, however, a much, much nicer way.
You could split this single file into multiple files, namely: header.hpp
and package.hpp
, and have them include eachother. However, there is one problem when doing this. When the headers recursively include eachother (or you include the same header multiple times), the types will be redifined over and over again. You need a way to only define the types once. This is done almost every time a header is used, by enclosing it with "inclusion guards". It looks like so:
#ifndef HEADER_HPP
#define HEADER_HPP
// Header code here
#endif /* HEADER_HPP */
That way, they'll only be declared once, but you can use both types in both files.
So your package.hpp
file will look like this:
#ifndef PACKAGE_HPP
#define PACKAGE_HPP
#include "header.hpp"
struct Package {
Header header;
};
#endif
And your header.hpp
will look like this:
#ifndef HEADER_HPP
#define HEADER_HPP
struct Header {
uint32_t Signature;
uint8_t MajorVersion;
uint8_t MinorVersion;
};
#endif