tags:

views:

153

answers:

5

This is the error I'm getting when trying to compile some code that uses taucs (not my code):

.../taucs/src/taucs.h:554: error: conflicting declaration ‘typedef struct taucs_ccs_matrix taucs_ccs_matrix’
.../taucs/src/taucs.h:554: error: ‘taucs_ccs_matrix’ has a previous declaration as ‘typedef struct taucs_ccs_matrix taucs_ccs_matrix’

wat? It is conflicting with itself?

After I pinched myself, I created a test header and put in a conflicting definition, just to make sure I was right about this:

In file testit.h:

#include "somethingelse.h"

typedef struct
{
  int n;
} foobar;

In file somethingelse.h:

typedef struct
{
  int n;
} foobar;

Sure enough, I get:

testit.h:6: error: conflicting declaration ‘typedef struct foobar foobar’
somethingelse.h:4: error: ‘foobar’ has a previous declaration as ‘typedef struct foobar foobar’

Or if I have this in testit.h:

typedef struct
{
  int n;
} foobar;

typedef struct
{
  int n;
} foobar;

testit.h:9: error: conflicting declaration ‘typedef struct foobar foobar’
testit.h:4: error: ‘foobar’ has a previous declaration as ‘typedef struct foobar foobar’

The line number is always different -- a declaration can't conflict with itself. I don't get it. Anyone ever seen this?

+3  A: 

Could it be that your header file (.../taucs/src/taucs.h), which contains the declaration, is (directly or indirectly) included twice by two separate #include directives?

Timwi
+1 for beating me to the punch on possible cause!
Harper Shelby
Thanks! I'm dumb today...
eeeeaaii
@Harper Shelby: +1 for that word "punch"
Chubsdad
I decided to give the checkmark to this answer since it came first.
eeeeaaii
+8  A: 

Is the single header included in multiple source files? If so, you need to wrap it in "include guards" like so:

#ifndef TAUCS_H
#define TAUCS_H

//Header stuff here

#endif //TAUCS_H
Harper Shelby
Thanks I just figured that out. I'm having a dumb day...
eeeeaaii
@eeee: You should accept this answer then with the checkmark.
Billy ONeal
You should avoid the leading double underscores, though. Those names are reserved.
jamesdlin
So are the trailing double underscores. A correct form would be `TAUCS_H`. C and C++ programmers won't use macros with _H suffixes for other purposes, so this is safe enough without further decoration.
MSalters
@jamesdlin, @MSalters: updated to reflect the good input.
Harper Shelby
A: 

Duh, I must be including the file twice. Duh!

eeeeaaii
A: 
typedef struct
{
   int n;
} foobar;

typedef struct
{
   int n;
} foobar;

testit.h:9: error: conflicting declaration ‘typedef struct foobar foobar’
testit.h:4: error: ‘foobar’ has a previous declaration as ‘typedef struct foobar foobar’

In this example you give 2 declarations of foobar. The compiler does not know which one to choose - so it bails out with conflicting declaration. You can't declare the same thing twice.

David Feurle
A: 

Don't repeat the definition. C++ allows a definition to only appear one time. What you can do is repeat a declaration.

A typedef is always a definition. So the first thing I would recommend is giving the struct proper a name (and since this is C++, a typedef does not add any benefit so just drop the typedef):

// file1.h
struct foobar
{
    int n;
};

Next, that should be in exactly one file. If you have files that only use pointers to foobar, you can repeat the declaration (just not the definition):

// file2.h

// This is just a declaration so this can appear as many times as
// you want
struct foobar;

void doit(const foobar *f); 
R Samuel Klatchko