0

I keep getting this Visual C++ 2010 LNK2005 linker error saying I have multiple definitions of two functions that are contained in "Error.h". (a header I made for error display)

My project is like this:

BaseImage.h BaseImage.cpp --> includes BaseImage.h , Error.h PNGImage.h --> includes BaseImage.h PNGImage.cpp --> includes PNGImage.h , Error.h main.cpp --> includes PNGImage.h 

And, of course, Error.h:

/* Optional macros: AE_EXIT_AT_ERROR */ #pragma once #include <stdexcept> void aeError(const char *str, int code=1) { throw std::runtime_error(str); #ifdef AE_EXIT_AT_ERROR std::exit(code); #endif } void aeAssert(bool b, const char *failStr = "assertion failed") { if(!b) aeError(failStr); } 

I have #pragma once in every header file, and I tried adding include guards to Error.h as well.

Here's the compile output:

1>PNGImage.obj : error LNK2005: "void __cdecl aeError(char const *,int)" (?aeError@@YAXPBDH@Z) already defined in BaseImage.obj 1>PNGImage.obj : error LNK2005: "void __cdecl aeAssert(bool,char const *)" (?aeAssert@@YAX_NPBD@Z) already defined in BaseImage.obj 1>C:\...\Project.exe : fatal error LNK1169: one or more multiply defined symbols found 

Could this be a bug?

1 Answer 1

2

When you define functions in a .h file, make them inline. Otherwise, the function definitions are part of the object code of all the .cpp files that #include it, with external linkage.

inline void aeError(const char *str, int code=1) { throw std::runtime_error(str); #ifdef AE_EXIT_AT_ERROR std::exit(code); #endif } inline void aeAssert(bool b, const char *failStr = "assertion failed") { if(!b) aeError(failStr); } 

The other option for you is to declare the functions in the .h file and define them in exactly one .cpp file.

The .h file:

extern void aeError(const char *str, int code=1); extern void aeAssert(bool b, const char *failStr = "assertion failed"); 

The .cpp file:

// Don't use inline and don't include the default argument values. void aeError(const char *str, int code) { throw std::runtime_error(str); #ifdef AE_EXIT_AT_ERROR std::exit(code); #endif } void aeAssert(bool b, const char *failStr) { if(!b) aeError(failStr); } 
Sign up to request clarification or add additional context in comments.

4 Comments

Does this mean that all the standard c functions (assert(), fread() etc..), that are declared globally, are inline?
@Pilpel, see the updated answer. Hope that clears up your doubts.
I made a Error.cpp that contains the functions, when Error.h contains only the definitions. The code still compiles when I omit extern from the functions declarations in Error.h. Is extern really needed?
No, extern is not needed for functions. It is needed for variables. Using it for both makes the declarations look consistent.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.