Keil Logo Arm Logo

*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Mike Hwang
Posted
19-Sep-2002 08:31 GMT
Toolset
None
New! *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
struct.h:
#ifndef _STRUCT_H
#define _STRUCT_H

int i;

#endif

main.c:
#include "struct.h"
void main(void)
{
	i = 1;
}

when compiled and linked,error is showed as follow:

Build target 'Target 1'
compiling main.c...
linking...
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
SYMBOL: I
MODULE: struct.obj (STRUCT)
Program Size: data=9.0 xdata=4 code=16
Target not created

What is the problem?
Note:no error if compiled in C compiler.
Read-Only
Author
Andrew Neil
Posted
19-Sep-2002 09:15 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
"no error if compiled in C compiler."

Well, of course there isn't: you can only get Linker errors from the Linker!!

See my reply here:
http://www.keil.com/forum/docs/thread1812.asp

Your file struct.h contains a definition of i; presumably you are also #includeing it in another 'C' source file (struct.c?) so that file will also contain a definition of i - presto! multiple definitions!

You need to define i in one file only (eg, main.c) and then just have an extern declaration in your header file.

BTW: 'i' is a particularly bad name for a global variable!
Read-Only
Author
Mike Hwang
Posted
19-Sep-2002 11:31 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
I think the two statements don't do any work as they do in C compiler in struct.h:
#ifndef
#define
Is that right?
You are right,Andrew Neil,I can use extern.
BTW:there are only the two files,main.c and struct.h in project
Read-Only
Author
Andrew Neil
Posted
19-Sep-2002 13:17 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
"I think the two statements don't do any work as they do in C compiler"

Pardon?
I don't understand what you're trying to say!

Those lines are a standard 'C' coding practice known as an Include Guard - their purpose is to prevent any problems if you (accidentally) #include the same file twice.
Read-Only
Author
Mike Hwang
Posted
19-Sep-2002 13:33 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
There aren't those two lines in any header files in INC directory of KEIL
why?
Read-Only
Author
Richard Collett
Posted
19-Sep-2002 13:18 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
If the only files in your project are main.c and struct.h, then where did struct.obj come from?
It certainly looks like two OBJ files are being linked together, and both of them contain a definition for "i".

The "ifndef" syntax used here is usually used to protect against the case where a header file is included twice, maybe because another header file references it. It does NOT mean you don't have to use "extern".

It is safest to make all variable declarations in ".h" files use extern, and then only actually declare the variable (without extern) inside one (and only one) ".c" file.
Read-Only
Author
Mike Hwang
Posted
19-Sep-2002 13:50 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
Originally I am puzzled by the OBJ file.
Really there are only two files in project,I have no idea where this OBJ file comes from.

Thanks to safest suggestion
Read-Only
Author
Mark Odell
Posted
19-Sep-2002 15:55 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
Dear Mike Hwang,

I think you need to brush up on your C before continuing on the embedded development path. Your problems stem from a lack of understanding about the C language.

1. Do *not* put code or define data in an include file. It is extremely bad style and error prone.

2. Always use include guards in your .h files but *don't* use leading underscores like the implementation header files do. Leading underscores followed by an uppercase letter or another underscore are reserved for use by the implementation.

3. If you want to share a global variable with another C module then define in it in one C module and extern it in that C module's .h file. Then, simply include that .h file in the other C modules that require knowledge of the global variable. E.g.

/* Foo.c */
int foo_var;

/* Foo.h */
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED

extern int foo_var;

#endif /* FOO_H_INCLUDED */

/* Bar.c */
#include "foo.h"

int main(void)
{
    foo_var = 12;
    return 0;
}

3. C source files must be compiled in to machine code if you want to run them. This code is typically placed in a relocatable object file, often with a .obj or .o extension. One or more object files are then passed on to the linker/locater which takes them and fixes up their relative addresses with absolute addresses. The linker also pulls object code from the C library at this stage too.

Hope this helps,

- Mark
Read-Only
Author
Andrew Neil
Posted
20-Sep-2002 20:36 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
You can include a header file which declares an identifier in the source file which defines that identifier; eg,
/* Foo.h */
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED

extern int foo_var;

#endif /* FOO_H_INCLUDED */


/* Foo.c */
#include "Foo.h"

int foo_var;
The advantage to doing this is that the compiler can warn you if the declaration doesn't match the definition

Read-Only
Author
Andrew Neil
Posted
19-Sep-2002 14:03 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
"If the only files in your project are main.c and struct.h, then where did struct.obj come from?"

Maybe he compiled struct.h - if you add a header to a uVision Project, it will get compiled unless you uncheck the 'Include in Target Build' option for the file.

"It certainly looks like two OBJ files are being linked together, and both of them contain a definition for 'i'."

Yes, if he did compile struct.h he would end up with a struct.obj containing a definition of i!

"It is safest to make all variable declarations in '.h' files use extern, and then only actually declare [sic] the variable (without extern) inside one (and only one) '.c' file."

This is where we need to take great care to distinguish between definitions and declarations:
A declaration simply informs the Compiler about an identifier; it creates no code and allocates no memory;
A definition actually provides the code to implement a function, or allocates the storage space for a variable.

Therefore, in general, declarations should go in headers and definitions in '.c' files - and multiple definitions in the same scope are not allowed.

(BTW: This is all standard 'C' stuff; nothing specifically to do with Keil.)
Read-Only
Author
Mike Hwang
Posted
20-Sep-2002 10:22 GMT
Toolset
None
New! RE: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
uncheck the 'Include in Target Build' option for the file.
good suggestion

At the end,thanks to everybody.

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Keil logo

Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.