5
g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5

I am having a problem and I seem to find out way I am getting this error.

file statemachine.h

#ifndef STATEMACHINE_H_INCLUDED
#define STATEMACHINE_H_INCLUDED

#include "port.h"

enum state {
    ST_UNINITIALIZED = 0x01,
    ST_INITIALIZED   = 0x02,
    ST_OPENED        = 0x03,
    ST_UNBLOCKED     = 0x04,
    ST_DISPOSED      = 0x05
};

void state_machine(event evt, port_t *port);

#endif /* STATEMACHINE_H_INCLUDED */

file port.h

#ifndef PORT_H_INCLUDED
#define PORT_H_INCLUDED

#include <stdio.h>

#include "statemachine.h"

struct port_t {
    state current_state; /* Error 'state does not name a type */
    .
    .
};
#endif /* PORT_H_INCLUDED */

Many thanks for any suggestions,

4 Answers 4

7

Could it be that you're including "statemachine.h" in "port.h" and "port.h" in "statemachine.h"?

Try removing the line:

#include "port.h"

From the file "statemachine.h"

Edit (as per Daniel's comment below):

Then you need to forward declare your port_t type as follows:

...
    ST_DISPOSED       = 0x05
};

struct port_t;

void state_machine(event evt, port_t *port);
...
Sign up to request clarification or add additional context in comments.

3 Comments

yes, that does solve the problem. But not I get another error because of this line. I did not show it my code snippet as I didn't think it was relevant void state_machine(event evt, port_t *port); This is in my statemachine.h file. So port_t *port is not defined. As that structure is in the port.h file. So not including it creates a new error. Thanks.
@ant2009, If you are intending to just use port_t* in your file then simply do a forward declaration as, class port_t; before you use it in your state_machine() function. That will solve the problem. Note that you will not be able to declare any object of port_t in statemachine.h file.
@Daniel, little bit confused. What am I purposed to be forward declaring? Thanks.
4

You need to have another header file, say, states.h which contains the state enum. Then both port.h and statemachine.h should include that header.

eg.
states.h

#ifndef STATES_H_INCLUDED
#define STATES_H_INCLUDED

enum state {
    ST_UNINITIALIZED = 0x01,
    ST_INITIALIZED   = 0x02,
    ST_OPENED        = 0x03,
    ST_UNBLOCKED     = 0x04,
    ST_DISPOSED      = 0x05
};

#endif

1 Comment

+1: This is the best way to solve the issue in terms of 'separation of concerns'.
1

Mutually included headers files are générally a bad idea in C++. As the include mechanism, is implemented by textual inclusion, then you'll find that the order of the definition in the resulting file will depend on which of the two file is included first. Since in your case, both of them depend on symbol exported by the other, there will always be some symbols (type in your case) that are not seen at the point of usage.

In you case, I'll recommend to move your enumeration in another file. So have a state.h file:

#ifndef STATE_H_INCLUDED
#define STATE_H_INCLUDED

enum state {
    ST_UNINITIALIZED = 0x01,
    ST_INITIALIZED   = 0x02,
    ST_OPENED        = 0x03,
    ST_UNBLOCKED     = 0x04,
    ST_DISPOSED      = 0x05
};

#endif /* STATE_H_INCLUDED*/

and then change statemachine.h to:

#ifndef STATEMACHINE_H_INCLUDED
#define STATEMACHINE_H_INCLUDED

#include "port.h"
#include "state.h"

void state_machine(event evt, port_t *port);

#endif /* STATEMACHINE_H_INCLUDED */

and port.h to:

#ifndef PORT_H_INCLUDED
#define PORT_H_INCLUDED

#include <stdio.h>
#include "state.h"

typedef struct port_tag port_t;

struct port_tag {
    state current_state; /* Error 'state does not name a type */
    .
    .
};
#endif /* PORT_H_INCLUDED */

Now, the file are not mutually included, the order is sanely defined, and everything should work correctly.

Comments

1

To break that circular dependency, do one of these two things :

  1. do not include port.h in statemachine.h, and forward declare instead
  2. move void state_machine(event evt, port_t *port); into port.h

Pick what makes more sense.


To forward declare, do this in statemachine.h :

#ifndef STATEMACHINE_H_INCLUDED
#define STATEMACHINE_H_INCLUDED

struct port_t;

enum state {
    ST_UNINITIALIZED = 0x01,
    ST_INITIALIZED   = 0x02,
    ST_OPENED        = 0x03,
    ST_UNBLOCKED     = 0x04,
    ST_DISPOSED      = 0x05
};

void state_machine(event evt, port_t *port);

#endif /* STATEMACHINE_H_INCLUDED */

you still have to include port.h in statemachine.cpp

2 Comments

Thanks for the answer. I am interested in 1. However, what do I forward declare? thanks.
Ok, added how to forward declare

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.