This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

getImage multiply defined (by retarget.o and init.o)

Hello,

I get this error message:

Symbol getImage multiply defined (by retarget.o and init.o)

In the headerfile init.h I have added all include data (like stdio.h and my own header-files) In one of these headerfiles I defined the struct variable getImage.

struct Image getImage;

So when I define this struct variable in the .c file - everything is working.

Peter

  • Object definitions do not belong in header files. Put definitions in one C source file and declare the object in a header file.

    See c-faq.com/.../decldef.html

  • Both retarget.c and init.c (or .cpp) include somehow one of your header files, in which you have the code:

    struct Image getImage;
    

    Keep in mind that because a line of code is in a header, doesn't change the fact that it will be compiled, as the rest of the code that follows in the c or cpp file.

    So when the compiler translates retarget.c, it will create retarget.o, in which a symbol called getImage (that has type struct Image) was created.

    When the compiler translates init.c, it will create init.o, but since it is going to hit the exact same line of code again (struct Image getImage), it will create another symbol, getImage, of type struct Image, in init.o.

    Then the linker complains that you have the exact same symbol, both publics, defined in two different object files (or more?).

    What you need is to have getImage created only once in your project. So you need to ensure that the line of code:

    struct Image getImage;
    

    appears in one, and only one c file (or cpp).

    Of course, if you have this line of code in a header, chances are that many c files will include it, and all those files will tell the compiler to define the exact same symbol.

    You need to have, in your header:

    extern struct Image getImage;
    

    That way, when you compile a file that includes this line, you just make a promise to the compiler that the object getImage is created somewhere else in your project, and the c code can use getImage, the compiler won't complain. getImage is not created, only the link to a symbol, that is suspected to exist in another .o file.

    AND, somewhere in a c file, it could be ANY file of the project (as long as it is linked at the end, so it could even be in a library):

    struct Image getImage;
    

    This time, getImage is created, but only once.

    Usually, headers are used to declare variables and functions, not to define them. Therefore, you need to use the extern keyword in headers.

    If getImage is used in only one c file, then there is no need to declare it anywhere else, just define it and use it in the same file. If getImage is used by several c files, then you need to declare geImage in each file that uses it, and to achieve that, putting the declaration (with the extern keyword) in a "popular" header (used by most files), is a common solution.

    If you want getImage to be accessible from only one translation unit (c file with headers), then you need to define it with the static keyword. That way, the symbol won't be exported to the linker and other c files won't be able to use the getImage variable that you defined in that very translation unit.

    'hope this helps...

    Steph-