i have defined an array in header file "Variables.h" and include it to source files. extern char LCD[11] = {0xF6, 0xC0, 0x6E, 0xEA, 0xD8, 0xBA, 0xBE, 0xE0, 0xFE, 0xFA, 0x00};
when am trying to compile i get the next message:
Build target 'Target 1' assembling LPC2300.s... compiling Main.c... compiling Interrupts.c... compiling Init.c... compiling LCD_ML1001.c... linking... Second Counter + TI8148.axf: Error: L6200E: Symbol LCD multiply defined (by interrupts.o and main.o). Second Counter + TI8148.axf: Error: L6200E: Symbol LCD multiply defined (by init.o and main.o). Second Counter + TI8148.axf: Error: L6200E: Symbol LCD multiply defined (by lcd_ml1001.o and main.o). Second Counter + TI8148.axf: Not enough information to list image symbols. Second Counter + TI8148.axf: Not enough information to list the image map. Second Counter + TI8148.axf: Finished: 2 information, 0 warning and 3 error messages. Target not created
"multiply defined" is an extremely ugly piece of English, and whoever wrote it should be shot.
It's bad enough for native English speakers, and I have every sympathy with non-native speakers who find it confusing.
See: www.keil.com/.../search.asp
A far better phrasing would be something like:
Error: L6200E: Multiple definitions of symbol 'LCD' (by interrupts.o and main.o). Error: L6200E: Multiple definitions of symbol 'LCD' (by init.o and main.o). Error: L6200E: Multiple definitions of symbol 'LCD' (by lcd_ml1001.o and main.o).
Now, think about it: If you put a definition in a header file, and then #include that header file in multiple source files, you are obviously going to get multiple definitions - aren't you?!
This is basic 'C' stuff - nothing specifically to do with Keil or ARM.
See: c-faq.com/.../decldef.html
This way of definition works in HIGHTECH C Compiler for Microchip
the answer is here http://www.keil.com/support/docs/3198.htm
i defined the type of array in header file than included it to c files and than i defined values of array elements in main.c before main function
Is that the one which doesn't do proper multi-file builds but, instead, (effectively) just #includes everyting into one compilation unit?
Also, there are some compilers that will assume that multiple definitions are supposed to be a sinlge definition - and treat them as such. I personally don't think that's a good idea - not without a warning, at least.
Yes - that is exactly what Per said to you.
It is also what the 'C' FAQ link said.
And what any good 'C' textbook would tell you.
Again, it is nothing specifically to do with Keil - it is standard, basic 'C' stuff.
"i defined the type of array in header file"
Do you mean you provided an extern Declaration of the array?
Defining a type is something different.
"i defined values of array elements"
You mean you provided a Definition of the array - with initialisation.
I think you still need to spend some more time reviewing these topics with a 'C' textbook or two...
"This way of definition works in HIGHTECH C Compiler for Microchip"
And you're ignoring all the warnings.
"Is that the one which doesn't do proper multi-file builds but, instead, (effectively) just #includes everyting into one compilation unit?"
No, it handles proper multi-file builds just fine.
"And you're ignoring all the warnings"
So is it one that does treat multiple definitions as a single definition, but warns you that it's done so?
"So is it one that does treat multiple definitions as a single definition, but warns you that it's done so?"
Yes, and those warnings should cause one to ponder: "Why all the fuss? What am I doing wrong?"
it is compiler specific. some compilers wouldn't complain about multiple but identical defines. others do.
'C' itself copes with multiple definitions of an object in a single compilation unit - see "tentative definitions".
The preprocessor allows multiple but identical #defines.
The error reported by the OP was a Linker error - not a compiler error.
The potential problem with the linker treating multiple but identical definitions as the same object is that it can't tell whether that was the programmer's intention or not - hence my opinion that a warning should, at least, be given.
I guess the counter argument is that the mistake illustrated here is so common that it is quite likely that it was, in fact, the programmer's intention...?
No, as a matter of fact, it doesn't. The whole business about tentative definitions exists so there will not be multiple definitions of the the same object, even in a single translation unit. This is achieved by specifying that something like
int foo;
is not, in and of itself, a bona fide definition. It's a declaration that may turn into a definition under certain conditions, to be resolved as the compilers proceeds with its work on the module. That's why it's called a tentative, i.e. a "may-be" definition. You can have multiple instance of that line in a single source file, and only one of them will actually be a definition. The others silently demote into declarations.
Even inside a single source file you can't have multiple actual definitions.
int foo=1; int foo=1;
This is not allowed to compile without complaint.
There is a common extension in this area where the tentative definition mechanism is widened from individual translation units to the whole program. I.e. tool chains supporting this extension (in the setting you're using) will merge multiple tentative-turned-actual definition into a single object at link time. But they won't do it for initialized definitions.