Author Topic: C typedef enum - what am I doing wrong here?  (Read 3318 times)

0 Members and 1 Guest are viewing this topic.

Online HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1477
  • Country: gb
C typedef enum - what am I doing wrong here?
« on: December 15, 2018, 08:42:09 pm »
I feel like I am going crazy. I've been banging my head against this for nearly an hour now. I'm 99.9% sure this should be working. What's going wrong here?

I have two header files. In one I have an enum declared, and in the other I have a struct that has a member of that enum type.

Code: [Select]
/* foo.h */

#ifndef FOO_H_
#define FOO_H_

#include "bar.h"

typedef enum {
XXX = 0,
YYY = 1,
ZZZ = 2
} foo_enum_t;

#endif

Code: [Select]
/* bar.h */

#ifndef BAR_H_
#define BAR_H_

#include "foo.h"

typedef struct {
/* other members */
foo_enum_t foo;
/* etc */
} bar_t;

#endif

And yet, when I compile, I'm getting the error "unknown type name 'foo_enum_t'" at the line in the struct in bar.h where I reference the enum type.

I don't believe I need to 'extern' my enum's typedef - in fact I don't think you even can. Is it maybe something getting confused by the recursive include of each header file within each other (i.e. foo.h includes bar.h, which includes foo.h...), but the include guards should avoid any trouble from that, right? If I include foo.h in some other different header file, the enum is known there and there are no compile errors. But these two headers need to include each other as foo's functions use the bar_t struct type.

|O :rant:
 

Offline paf

  • Regular Contributor
  • *
  • Posts: 91
Re: C typedef enum - what am I doing wrong here?
« Reply #1 on: December 15, 2018, 08:46:14 pm »
You are including "bar.h" in  "foo.h". 

Not needed.

 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1530
  • Country: gb
Re: C typedef enum - what am I doing wrong here?
« Reply #2 on: December 15, 2018, 08:49:35 pm »
Quote
, but the include guards should avoid any trouble from that, right?
Nope. The include guard simply stops the same definitions from being re-defined if they have been defined before from the same header.

Whenever you do a #include the compiler will always load and paste the entire header file into the file being compiled.
 

Offline tsman

  • Frequent Contributor
  • **
  • Posts: 599
  • Country: gb
Re: C typedef enum - what am I doing wrong here?
« Reply #3 on: December 15, 2018, 08:53:18 pm »
You included foo.h which sets FOO_H_ then includes bar.h which tries to include foo.h again but FOO_H_ is already set so does nothing. It continues parsing bar.h and now comes across foo_enum_t which it has no clue about so gives that error. It is only after it has finished parsing bar.h that it continues with the rest of foo.h and sees the enum but it has already failed with an error by this point.

 

Online HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1477
  • Country: gb
Re: C typedef enum - what am I doing wrong here?
« Reply #4 on: December 15, 2018, 08:56:04 pm »
Really? I could swear I've done this kind of thing before without any problems. Maybe the mind is playing tricks on me... :palm:

It's going to be a pain if I have to, say, make a third include file and put both enum and struct into that, as that'll be blurring functionality and logical boundaries. My code is all so nicely organised at the moment. :'(
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: C typedef enum - what am I doing wrong here?
« Reply #5 on: December 15, 2018, 10:08:45 pm »
You didn't show main.c so who knows which order the includes are in.  If, in main.c, you include only bar.h, the code should compile.  I think...

When bar.h is expanded, it will include foo.h which will try to include bar.h but that's already blocked so foo.h will create the typedef and bar.h should use it.

Code: [Select]
#include "stdafx.h"
#include "bar.h"

bar_t FooBar;

int main()
{
    return 0;
}


This seems to compile...
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: C typedef enum - what am I doing wrong here?
« Reply #6 on: December 16, 2018, 01:49:26 am »
But these two headers need to include each other as foo's functions use the bar_t struct type.

No, this is where you went wrong. bar.h needs foo.h, but foo.h has no need of bar.h. So why include bar.h in foo.h? Especially since it fails for obvious reasons if bar.h ends up being declared prior to foo.h.

The value of include guards is so that multiple references to the same include file pass muster. e.g. if bar.h includes foo.h, and squared.h also includes foo.h, you don't have a problem including both bar.h and squared.h. Recursive references are an usually only a step away from total failure, even when you get away with it. Never do that on purpose!
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11891
  • Country: us
Re: C typedef enum - what am I doing wrong here?
« Reply #7 on: December 16, 2018, 02:32:57 am »
...the recursive include of each header file within each other...

This is always a bad idea, and will always need to trouble. A better description of "recursive include" is "circular dependency". You do not want circular dependencies, ever. If you have a circular dependency you have done something wrong.
 
The following users thanked this post: nugglix

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: C typedef enum - what am I doing wrong here?
« Reply #8 on: December 17, 2018, 02:47:46 am »
As @rstofer said: the key to your problem is whether you are including foo.h or bar.h in your .c file.

If you include bar.h, your file should compile OK

If you include foo.h, you will get exactly the problem you describe.

// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 

Online HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1477
  • Country: gb
Re: C typedef enum - what am I doing wrong here?
« Reply #9 on: December 17, 2018, 07:12:24 pm »
I managed to resolve the issue, by re-evaluating how in general I was handling all my included headers across the project.

Basically, I realised I would be better off not including things in the .h files of a module that aren't actually necessary in facilitating the inclusion of that .h in another module - rather, I should split the things that are included between a module's .h and .c. The .h will only include the things that are required to express function definitions, struct, enums, etc (e.g. stdbool, stdint). Anything else: in the .c.

Doing this meant that the inclusion of bar.h was moved to foo.c, and so - as I suspected and was rightly pointed - a circular dependency was avoided.

Thanks for the help everyone.
 

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: C typedef enum - what am I doing wrong here?
« Reply #10 on: December 17, 2018, 08:35:08 pm »

Doing this meant that the inclusion of bar.h was moved to foo.c, and so - as I suspected and was rightly pointed - a circular dependency was avoided.

Thanks for the help everyone.

Sorry - you really need to understand why it was a problem in the first place. It was NOT a problem with circular dependency, but misunderstanding of... a bunch of things.
// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf