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
Do you think it would make a difference if your header file contained:
extern char LCD[];
and one of your C files contained:
char LCD[11] = {0xF6, 0xC0, 0x6E, 0xEA, 0xD8, 0xBA, 0xBE, 0xE0, 0xFE, 0xFA, 0x00};
Any idea why the above might make a difference?
"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.
"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};"
that's a declaration - which requires reserving space for LCD[]. and you aren't supposed to have put that in the header files - because inclusion of such header files will create multiple instances of LCD[] and the compiler obviously wouldn't know which LCD you are referrering to when your code makes a reference to LCD[].
the eay to go is to declare LCD[] in your C file:
"char LCD[11] = {0xF6, 0xC0, 0x6E, 0xEA, 0xD8, 0xBA, 0xBE, 0xE0, 0xFE, 0xFA, 0x00};"
and then in the header file:
"extern char LCD[11];"
this tells the compiler / linker that there is this array whose space is already allocated somewhere else.
'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...?
Actually, that's a Definition.
The Definition is what reserves the space; A Declaration just "declares" that the space is (assumed to be) defined elsewhere.
"there can be many declarations (and in many translation units) of a single global variable or function, there must be exactly one definition" c-faq.com/.../decldef.html
c-faq.com/.../index.html c-faq.com/.../index.html
To me, HIGHTECH C Compiler is special, mainly because the traditional PIC MCU is C unfriendly.
like:
HI-TECH C for PIC10/12/16 User's Guide 3.8.3 Function Duplication It is assumed by the compiler that an interrupt may occur at any time. As all functions are not reentrant (because of the dependance on the compiled stack for local objects, see Section 3.4.2 “Compiled Stack Operation”), if a function appears to be called by an interrupt function and by main-line code this could normally lead to code failure. HI-TECH C has a feature which will duplicate the output associated with any function called from more than one call tree in the program’s call graph. There will be one call tree associated with main-line code, and one tree for the interrupt function, if defined.