Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

repeat typedef struct

Name: Anonymous 2010-01-12 1:18

Why can't I repeat a typedef struct in C? Why is it allowed in C++ but not C?

I'm running into problems with my header files. Let's say I've got structs Foo, Bar, and Baz. I'd like Foo functions to take Bar and Baz pointer arguments. I shouldn't need to include their header files in Foo.h however; it should just take a forward declaration to reduce interdependency and compilation time. However the multiple declarations break in Foo.c.

Example: (include guards not shown)

// Bar.h
typedef struct Bar {
  int x;
};


// Baz.h
typedef struct Baz {
  float y;
};


// Foo.h
typedef struct Bar Bar;
typedef struct Baz Baz;
typedef struct Foo {
  Bar* bar;
  Baz* baz;
};

void FooABar(Foo* self, Bar* bar);
void FooABaz(Foo* self, Baz* baz);


// Foo.c
#include "Bar.h"
#include "Baz.h"
#include "Boo.h" // ERROR, duplicate typedefs

// implementations follow


So, how do I solve this problem? Just including the other headers in Foo.h works here, but it has the dependency issues, and only works because the relationship is one way; if Baz has some methods take take Foos, this doesn't work. I'm quite wary of unnecessary includes; my last few sepples projects take AGES to compile despite being small because of interdependencies, and I'd really like to avoid this with this next C project.

Best solution I can come up with is just to forward declare struct Bar, and use that as the pointers everywhere instead of just Bar. Is this really what I need to do? If this is the case, I'm thinking I'll just axe the typedefs altogether throughout my entire project. I hate having to write struct everywhere, but I would do it for consistency... How does everyone else solve this?

Name: Anonymous 2010-01-12 1:32

OP here, a couple solutions I've been thinking of are:

- Just put up with the extra dependencies, and use the struct keyword if a circular dependency is required. This is the least elegant solution that is still portable.

- Write struct everywhere. I'd feel like it's the 70s/80s, and the code would look like it too.

- Put all forward declarations for all structs in the module into its own header file, which does all the typedefs. This is how e.g. <isofwd> works to solve a (sortof) similar problem in sepples. The new problem is now that any time I add a struct, I have to recompile *everything*. Not a huge deal if compilation is fast... Example:

// fwd.h
struct Foo;
typedef struct Foo Foo;
struct Bar;
typedef struct Bar Bar;
struct Baz;
typedef struct Baz Baz;


- Do some preprocessor trickery. Example:

struct Bar_S;
#undef Bar
#define Bar struct Bar_S


That's a lot of boilerplate to forward declare things, and makes the visible code frighteningly different from what the compiler sees. What problems would this cause? Can I simplify this in any way?

- Just compile the fucking thing as C++, or rely on a compiler attribute or pragma to let me do it.

Yeah, this is the worst solution. It would work, sadly.

Thoughts?

Name: Anonymous 2010-01-12 2:30

The fuck do you think
typedef struct Bar {
  int x;
};

does?

Name: Anonymous 2010-01-12 5:07

EXPERT PROGRAMMING ITT

Name: Anonymous 2010-01-12 7:03

forward declaration
Now you have two problems.

Name: Anonymous 2010-01-12 10:10

>>3
Just a typo, obviously I meant:

typedef struct Bar {
  int x;
} Bar;

Name: Anonymous 2010-01-12 10:57

My solution to this in a small project was to make a forward declaration header file, which was included by the main header file so that all the .c files could use the structures. The downside obviously is that you must maintain this file; you could write a script to generate the forward declarations from all other header files, but then you increase compilation complexity.

The real solution is to make a new systems language with module support, but the C standard will probably never change so much because it would break millions of lines of existing code.

Name: Anonymous 2010-01-12 12:18

My solution is to use a language that isn't C++.

Name: Anonymous 2010-01-12 17:09

U MENA HASKAL?

Name: Anonymous 2010-01-12 19:20

>>8
Well that's nice, since this is C. C++ doesn't have this problem, because a) it allows referring to struct tags without the keyword, and b) it allows duplicate typedefs, either of which solve the problem. Nice fail.

>>7
Yeah, I think I'll probably do this. Pretty shitty but, ah well, better than writing struct everywhere.

the C standard will probably never change so much because it would break millions of lines of existing code.
Allowing duplicate typedefs wouldn't actually break anything; it's just a relaxation of the current rules. But you're right though, no one seems to care about this issue so it will never change.

Name: Anonymous 2010-01-13 9:26

>>10
As if I actually read the thread.

Name: Anonymous 2011-02-03 1:50

Name: Anonymous 2011-02-03 7:27

Don't change these.
Name: Email:
Entire Thread Thread List