Multiple definition of ...


#1

After 2 years of (happy) idle time, I find myself in the necessity of migrating my old OpenAT projects (based on VS6) to this new Eclipse-based environment. I have solved all the issues related to changes in OpenAT libraries, and all my c files now compile. The problem arises when linking:

For every variable I declare in my header files I recieve the error message
multiple definitions of …
I have read the thread [url]https://forum.sierrawireless.com/t/migrating-to-m2m-studio-from-vs-2008/4148/1] and came up with the explanation:

Well, in my header files, all variables are simply declared, never defined.


#2

By some reason I was not allowed to include a sample code in the previous post. Here is a sample of the lines in my headers that are giving me such a ‘headache’.

s8	hData;
bool	bPortReady;
bool	bLastReadingOK;
bool	bProgramPaused;

#3

That way should look your .c file, not the header. You should have:
//xx.c
s8 hData=0;
bool bPortReady=FALSE;
bool bLastReadingOK=FALSE;
bool bProgramPaused=FALSE;

//xx.h
extern s8 hData;
extern bool bPortReady;
extern bool bLastReadingOK;
extern bool bProgramPaused;


#4

Not according to the sample which you posted:

Those are definitions!

Read that FAQ again: c-faq.com/decl/decldef.html


#5

I wish it was that easy!

That’s not the case. I’ve even commented out any line that used some of such variables, so in fact the only reference across my project to those variables is their declaration in the .h file, and still is marked as “multiple-declared”.

Thanks for the reply anyway.


#6

awneil, accordong to the link you provided:

… my code are declarations (not definitions, the variables are not initialized). On the other hand, if you insist on my sample code being definitions, then: how should I declare a shared variable?


#7

Read that link again, more carefully:

The ‘extern’ is the key!

An initialisation is sufficient to make a definition - but it is not necessary.

As Flex told you, your header file should contain just the extern declarations; eg,

If you think about the purpose of header files, this should be obvious: the header is telling the compiler that these variables will be defined somewhere externally to the current compilation unit.

You must then provide definitions in exactly one of your ‘C’ source files; eg,

The definition is the thing which actually causes resources to be committed

I do - as does the definition of the ‘C’ programming language!


#8

Now I am beginning to understand things!

1.- Developer Studio is using a C++ compiler to compile my C files. Can that be changed?
2.- It is not enough to correct the .h files: the GUI is so “clever” that it won’t mark affected .o files as outdated, so changes made to .h files will have no impact on final result.

Thanks for your patience, awneil; in my old C-way thinking, “extern int a;” and “int a;” at file-scope are equivalent.


#9

No, that’s not true.

It’s using GCC which, like the VS6 compiler, can do both ‘C’ and C++.
It should be automatically assuming that .c files are to be compiled as ANSI ‘C’

This is a known bug: https://forum.sierrawireless.com/t/dependencies-not-generated-properly/3941/1

Doing a ‘Clean’ will rebuild using the modified files (be sure that the changes have been saved!)

No, that has never been the case!


#10

You can read the whole chapter here:
http://menehune.opt.wfu.edu/Kokua/More_SGI/007-0701-150/sgi_html/ch07.html#Z35064

This is not the reference I use, but I am pretty sure I read the same thing in my books 20 years ago when I started programming in C.


#11

But that’s declarations - you had definitions!


#12

optomation take it like a man and move forward, no need to continue, problem solved after all :wink:


#13

There’s also the possibility of labelling variables in header files as “static”, however I prefer to use constructs such as the following:

//bearer.h
#ifndef BEARER_H_
#define BEARER_H_

#ifdef BEARER_C
  #define EXTR_BEARER
#else
  #define EXTR_BEARER extern
#endif


#ifndef BEARER_H_
#define BEARER_H_

#ifdef BEARER_C
  #define EXTR_BEARER
#else
  #define EXTR_BEARER extern
#endif

//stuff

EXTR_BEARER <type> <name>;

// ------------------------------------------------------------------------------------------------

#endif	//BEARER_H_

//bearer.cpp
#define BEARER_C
#include "bearer.h"

#14

What would be the point of that??

See: https://forum.sierrawireless.com/t/static-in-headers-whats-all-that-about/4327/1


#15

Too verbose I think. It is shorter to use hard coded ‘extern’ in headers and definitions in .c files. And much better not to use global variables at all.


#16

Sorry, don’t get you there - in what way “verbose”?


#17

Too much code for nothing. Sorry for bad english.


#18

Yes - I think that’s what the ‘C’ FAQ means when it says,

As for the use of static, that’s not just a matter of no benefit - it is (potentially) plain wrong.


#19

Maybe one file includes himself.
Or fileA includes fileB that includes fileA…


#20

No - if anything, that would cause Compiler errors - these are Linker errors!