error multiple definition without 'static'

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I have strange problem:

e.g. I have files "main.h" , "main.c" , "abc.h" and "abc.c"

In "main.h" is included "abc.h".

In abc.h is:

const char text[] PROGMEM = "string in progmem";

there's error when building project:

abc.o:(.progmem.data+0x0): multiple definition of `text'
main.o:(.progmem.data+0x0): first defined here

When I add third ".h" file and include 'abc.h' than I have 2x multiple definition error (of course I have #ifndef .... #define ... in all header files)

but when I add "static" in abc.h :

static const char text[] PROGMEM = "string in progmem";

everything is ok - no errors

Could somebody explain what's the matter?

ps. using avr-gcc in eclipse + Dean's makefile from LUFA example

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

In abc.h is:

You don't put the data in the .h you put an EXTERN to the data. That's your problem. Read the "Managing Large Projects" article in the Tutorial Forum which explains how to place data and use extern (and function prototypes). Bottom line: never put anything that would allocate ANY form of storage into a .h file

(static inline functions are a slight exception but they don't generate code where written - they generate it where invoked in .c files)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know it, but what about variables stored in progmem? they require also initialization (am I wrong?).

Of course I can declare & initialize in *.c file, but how to share this variable to other files? extern in *.h doesnt work if it's e.g. string table.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kaczart wrote:
I know it, but what about variables stored in progmem? they require also initialization (am I wrong?).

Of course I can declare & initialize in *.c file, but how to share this variable to other files? extern in *.h doesnt work if it's e.g. string table.

And one more thing, sometimes I don't even need *.c file, e.g. my lcd graph font library

// fonts.h

static char PROGMEM  font5x7[] = {
0x00, 0x00, 0x00, 0x00, 0x00,// (space)
0x00, 0x00, 0x5F, 0x00, 0x00,// !
0x00, 0x07, 0x00, 0x07, 0x00,// "
0x14, 0x7F, 0x14, 0x7F, 0x14,// #
0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
0x23, 0x13, 0x08, 0x64, 0x62,// %
//........

just why it don't want to work without static...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I know it, but what about variables stored in progmem? they require also initialization (am I wrong?).
Yes, but that is done in the .c file just like any other variable.
Quote:
extern in *.h doesnt work if it's e.g. string table.
Why do you say that?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok, let's write sth like this in "*.c" file:

const char text[] PROGMEM = "text in progmem";

what should be declaration in "*.h" file if I don't know size of array?

thanks for replies.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kaczart wrote:
ok, let's write sth like this in "*.c" file:

const char text[] PROGMEM = "text in progmem";

what should be declaration in "*.h" file if I don't know size of array?


extern const char text[];

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 warning: array 'text' assumed to have one element
 Warning: size of symbol `text' changed from 1 in main.o to 8 in abc.o
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You either forgot the "extern", or you made something silly like "#define extern".

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
You either forgot the "extern", or you made something silly like "#define extern".

no, I'm not ;)

It would be everything ok, if variable wont be string array in PROGMEM or if I specify array size

//.h
extern const char text[10];

//.c
const char text[] PROGMEM = "123456789";

but this way is useless for me

it's everything ok when i add 'static' and initialize in 'h


//.h
static const char text[] PROGMEM = "123456789";

question is: why without static doesnt work? what is better/another way?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kaczart wrote:
sternst wrote:
You either forgot the "extern", or you made something silly like "#define extern".

no, I'm not ;)

There must be something like that. Review your header files and have a look at the preprocessed files (.i).
You get the warning/error only if the "extern" is not there.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i'm confused, everything is working on second computer.. and still is not on first one (the same project, ide, and winavr)

is it possible that SSD hybrid drive "remember" too much?

very strange.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

and still is not on first one (the same project, ide, and winavr)

So copy the entire thing from one to the other and "diff".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kaczart wrote:
question is: why without static doesnt work? what is better/another way?
It's not working with static either.
static gives you a separate legal, but probably not what you want copy, in every .c file in which the .h file is #included.

The problem you are experiencing is not specific to avr-gcc.
A global variable, whether or not an array, must be initialized precisely once within an entire program,
therefore a .h file should never contain initialization data.
A declaration of a global variable without an extern is an initialization,
therefore in a .h file, declarations of global variables should have extern's.

Moderation in all things. -- ancient proverb