Hey all, I'm getting an L1818 error, "Symbol duplica...

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Hey all, I'm getting an L1818 error, "Symbol duplica...

4,223 Views
irob
Contributor V
Hey all, I'm getting an L1818 error, "Symbol duplicated in first file and second file."  My project setup is this:

(main.c)
#include "main.h"

(file2.c)
#include "main.h"

(main.h)
const Byte table1[]=
{
  0x00,
  0x01   // e.g.
}

It made sense to me to put this table in my header, since they aren't variables.  They're empircal hex values for a lookup table.  Nevertheless, it's actually only main.c that calls the function which uses this table.

I have found that if I move that table out of main.h and into main.c, the error goes away.  But again, organizationally, it makes most sense to me to stuff it into the header with all the other defines and junk.

I suspect that this thread is related to my problem, but not sure.  Any suggestions?
Labels (1)
Tags (1)
0 Kudos
5 Replies

957 Views
CompilerGuru
NXP Employee
NXP Employee
Move the definition of the constant into the *.c file, if anything except main.c needs to access table1 too,
add a  declaration to the header file.

E.g: only used in main.c:
main.c:
#include "main.h"
static const Byte table1[]=
{
  0x00,
  0x01   // e.g.
};
main.h:
// nothing about table1.

E.g. table1 used in main.c and elsewhere too.

main.c:
#include "main.h"
const Byte MAIN_table1[]=
{
  0x00,
  0x01   // e.g.
};
main.h:
// nothing about table1.
#ifndef MAIN_H_
#define MAIN_H_
extern const Byte MAIN_table1[]; /* defined in main.c */
....

#endif /* MAIN_H_ */

Notes:
If it is used only in main.c, make it static so the name is not visible elsewhere and can not cause any name collisions.

If it is used elsewhere, make sure the name is unique in the project, e.g. by a MAIN_ suffix.
Declare it in the header, define it in main.c.

Note that the same rules apply for constants, variables and for functions too.

Daniel

0 Kudos

957 Views
irob
Contributor V
Ok, so I guess I stumbled upon the solution (putting it in main.c only).  I definitely didn't know about that complier (linker?) suffix "MAIN_".  Thanks.

In the case of functions and variable, I've been simply using "extern" calls in the souce C files if those functions/variables originate in other source files.
0 Kudos

957 Views
allawtterb
Contributor IV


irob wrote:
Ok, so I guess I stumbled upon the solution (putting it in main.c only).  I definitely didn't know about that complier (linker?) suffix "MAIN_".  Thanks.

In the case of functions and variable, I've been simply using "extern" calls in the souce C files if those functions/variables originate in other source files.



There isn't anything "special" about using MAIN_ as a prefix or suffix to a name.  It was only mentioned as a way to make a name unique.  If you wanted a table in timer.c to be accessed externally you might use TIMER_table as the name.
0 Kudos

957 Views
irob
Contributor V
Ahh, gotcha.  I was thinking it was some sort of segmentation syntax, like "__SEG"
0 Kudos

957 Views
bigmac
Specialist III
Hello,
 
Further to Daniel's explanation - the general rule would appear to be that, for a definition (something that generates code, or allocates memory), this can only occur once, and it is safer for this to be within a single .c file, and not a header file.  However, for a declaration (that does not allocate any memory), this is suitable for a header file.
 
static const Byte table1[] = {0x00, 0x01};
clearly allocates memory, whereas the declaration 
 
extern const Byte table1[];
does not allocate any memory.
 
Within the CW IDE, after a compile, if you see that a header file has a non-zero value for code or memory requirements, it is a good idea to investigate further to try and eliminate any future potential problems with multiple includes.
 
Another potential issue with your code might be the use of the Byte typedef (or macro).  Obviously, the file in which table[] is defined should already know about the typedef.  However, this is not necessarily the case for another file that simply requires to use values from the table.
Therefore, any header file that uses the typedef should also include the header file that defines the typedef, or might alternatively incorporate (assuming a typedef rather than a macro) -
 
#ifndef Byte
typedef unsigned char Byte;
#endif
 
Regards,
Mac
 
0 Kudos