'lo there folks,

MinGW's giving me 1 error I can't get rid of:

eventhandler.h|9|error: `element' has not been declared|
eventhandler.h|9|error: ISO C++ forbids declaration of `elem' with no type|

All code mentioned and I think needed:

eventhandler.h

#ifndef EVENTHANDLERH
#define EVENTHANDLERH

#include "element.h"

enum events {onClick, onHover};

typedef struct eventHandlerT {
    void(*func)(element *elem);
    events eventType;
} eventHandler;


#endif // EVENTHANDLERH

element.h

#ifndef ELEMETH
#define ELEMETH

#include "eventhandler.h"

class element {
    public:
    element();
    ~element();

    void processEvent(events event);

    vector<eventHandler> handlers;
    unsigned int ID;
    static unsigned int IDcount;
};


#endif // ELEMETH

Why is element not declared? I don't get that, the header is included right above it?

Any help is greatly appreciated,

Dani AI

Generated

The error comes from a circular dependency between the two headers. As pointed out, include guards only stop a file being processed twice — they do not resolve a situation where file A includes file B and file B includes file A. Forward-declaring the other class in one header (and including the full definition only where it is actually needed, typically in the .cpp) breaks the cycle and fixes the compile error, which is what observed.

A quick rule of thumb: a forward declaration is sufficient when the header only needs a pointer or reference to the type. It is not sufficient when the header needs the complete type. For example:

class B;  // forward declaration

class A {
    B* ptr;   // OK with forward declaration
    B  obj;   // Error: incomplete type, requires full definition
};

Common situations that require the full type (not just a forward declaration):

  • member data by value (not pointers/references);
  • inheritance (base classes must be complete);
  • calling member functions or accessing members (you need the type definition);
  • using sizeof or other compile-time size operations;
  • certain template/container operations — e.g., if a class has std::vector<T> as a member, T must be complete by the time the destructor (or other inlined member functions) is instantiated. A practical fix is to define the destructor (or other functions that touch the container) in the .cpp after including the full T definition.

Practical tips:

  • Move shared enums/POD types into a small separate header to break coupling.
  • Forward-declare where possible and include the real header in the .cpp.
  • Prefer std::function or pImpl to reduce header-level dependencies.
  • Use g++ -H (or your compiler's include tracing) to inspect include chains.
  • Make sure to #include <vector>/<functional> and use std::vector/std::function where appropriate.

Following those patterns keeps headers lightweight and avoids the "has not been declared" cycle you hit.

Recommended Answers

All 4 Replies

>>Why is element not declared?
Because you have recursive includes -- each header file includes the other.

In eventhandler.h try this:

#ifndef EVENTHANDLERH
#define EVENTHANDLERH

class element;  // forward declaration of class

enum events {onClick, onHover};

typedef struct eventHandlerT {
    void(*func)(element *elem);
    events eventType;
} eventHandler;


#endif // EVENTHANDLERH

Thanks, it works, but...

That's where the guards (the #ifdef stuff) are for right? Not trying to be impolite, but why can't I include those headers with the guards in place?

>>That's where the guards (the #ifdef stuff) are for right?

Nope. The guards prevent the same include file from being processed more than once. For example:

#include "element.h"
#include "element.h" // this one will be ignored

Your program had a different problem. The preprocessor attempted to process the line that used element *elm but class element had not been fully defined yet. With forward references the class doesn't have to be fully defined in order to declare a pointer to it.

Ah, okay. Thanks for the explanation.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.