Alex Rivera | Logout

redefinition of typedef

Asked 2011-12-03T12:29:53.917
27

I am possibly doing this incorrectly and this is much a question about why it works in one compiler and not the other.

I have a large C application, and I am trying to follow the style of not including header files from within other header files. Instead, using forward declarations; thus I am trying the following.

// in A.h
typedef struct A_ A;
typedef struct B_ B;
struct A_ {
    double a;
    B *b;
};

// in B.h
typedef struct B_ B;
struct B_ {
    int c;
};

// in C.h
typedef struct A_ A;
typedef struct B_ B;
void function_do_something(A*, B*);

// in C.c
#include "A.h"
#include "B.h"
#include "C.h"
void function_do_something(A* a, B* b) {
    ...
}

This paradigm compiles and runs in Ubuntu 11.10 gcc -- but it gives compiler erros in OpenSUSE gcc that say "redefinition of typedef".

I have been doing my development in Ubunutu and so hadn't realised that this paradigm might be incorrect. Is it just that this is plain wrong and Ubuntu's gcc is being too nice?

Edit
Report

3 Answers

6

One piece of the idiom is missing. The forward declarations are independent from the definitions, so they should be in a separate header file.

// a_fwd.h

#ifndef A_FWD_H
#define A_FWD_H

typedef struct A_ A;

#endif

// a.h

#ifndef A_H
#define A_H

#include "a_fwd.h"

struct A_ {
};

#endif

Now it's always safe to include any headers in any order.


It is illegal to have two definitions of anything. A typedef is a definition, not just a declaration, so the one compiler was being quite lax to allow the redundancy.

answered 2011-12-03T14:22:32.713
0

You are redefining A and B by writing the same statement in several header files. One solution would be to drop the typedef of A and B from the A.h and B.h and use your C.h as it is.

answered 2011-12-03T12:43:56.213
-2

You are defining multiple times the same thing.

You can spread it across multiple header files just have to make sure that there is some B seen before struct _A is defined.

This code works:

#include <stdio.h>

typedef struct _B B;
typedef struct _A A;

struct _A {
    double a;
    B *b;
};

struct _B {
    int c;
};

void function_do_something(A* a, B* b)
{
    printf("a->a (%f) b->c (%d)\n", a->a, b->c);
}

int main()
{
   A a;
   B b;

  a.a = 3.4;
  b.c = 34;

  function_do_something(&a, &b);

  return 0;
}

Output:

> ./x
a->a (3.400000) b->c (34)

EDIT: updated for C

EDIT 2: spread into multiple header files

b.h:

#ifndef B_H
#define B_H

struct _B {
    int c;
};

#endif

a.h:

#ifndef A_H
#define A_H

typedef struct _B B;

struct _A {
    double a;
    B *b;
};

typedef struct _A A;

#endif

main.c:

#include <stdio.h>

#include "a.h"
#include "b.h"

void function_do_something(A* a, B* b)
{
    printf("a->a (%f) b->c (%d)\n", a->a, b->c);
}

int main()
{
   A a;
   B b;

  a.a = 3.4;
  b.c = 34; 

  function_do_something(&a, &b);

  return 0;
}
answered 2011-12-03T12:46:00.813

Your Answer