C++ linker strange behavior: static member variable - c++

I'm stuck in a linker error and need some help. I'm using MSVC.
At the beginning, I made this:
/* graphics_app.h */
#ifndef DK_GRAPHICS_APP_H
#define DK_GRAPHICS_APP_H
...
class GraphicsApp {
private:
static GraphicsApp* self;
...
};
GraphicsApp* GraphicsApp::self = nullptr;
#endif /* DK_GRAPHICS_APP_H */
This header used to work... and I made some improvements, but nothing about that static member changed.
but unexpectedly I got this linker error message:
LNK2005 "private: static class GraphicsApp * GraphicsApp::self" (?self#GraphicsApp##0PEAV1#EA) already defined in main.obj.
LNK1169 one or more multiply defined symbols found.
So, I separated this header into .h and .cpp:
/* graphics_app.cpp */
#include "graphics_app.h"
...
GraphicsApp* GraphicsApp::self = nullptr;
but I got another error:
LNK2001 "private: static class GraphicsApp * GraphicsApp::self" (?self#GraphicsApp##0PEAV1#EA) unresolved external symbol.
LNK1120 1 unresolved externals.
Why these weird behavior happens & how can I fix?
EDIT:
I made test version to make problem simper.
This thing happens when I use my custom include directory...
such as
#include <dk/graphics_app.h>
instead of
#include "graphics_app.h"
So.. a new problem is, how can I fix this whilst using my custom include directory?
Edit2:
To make Thing much simpler..

LNK2005:
This error happened because, the header file was included in two other cpp files (compiled to obj files) . Then when the linker tried to link the obj it found two of the same definitions. But "there can be only one"!
Because of this ambiguity the linker gives up.
LNK2001:
This error happened because the linker did not find the defined variable in any obj file. So I think that the new cpp is missing from your project definition.

This header used to work... and I made some improvements, but nothing about that static member changed.
Your header is written incorrectly: you are not supposed to put definitions of entities with external linkage into header files. It could "work" as long as you included your header file into one and only one translation unit. But once you include it into two or more different translation units, you get the "multiple definition" error. Which is exactly what happened in your case.
So, I separated this header into .h and .cpp
This is the right thing to do. Now you have to make sure your graphics_app.cpp is compiled (and linked) as part of your program. This is something you forgot to do. The compiler/linker/build system cannot somehow "magically" realize by itself that your freshly created graphics_app.cpp is supposed to be part of your project.

Related

LNK2019 Unresolved external symbol OOP and polymorphism?

My project is to build a stack in C++, And I implemented it using array ,but I have 6 Errors: all of them
LNK2019 Unresolved external symbol to some functions implementation in the .CPP file I know this is a linker errors , the problem occurred when I Divided My code into Header files .h and implementation files .cpp but the syntax is alright and the program The program has run correctly when I had to test the code in on file :the main file ,any solutions please?
this is the link of code:
https://github.com/MohamedYehiaShahin/stack-usin-array-c-
Since you didn't post your code, I can only guess. If you are implementing your stack using a template (very common) then you may see this error if you define your template functions/methods in a separate .cpp file. Typically template functions & classes are defined inline or contain their definitions within the same header file as their declarations.

How to include an external header file when I have 1 header for 2 .cpp files?

I have one header file and two .cpp files.
E.g. normal.h, normal.cpp, abnormal.cpp.
I have included the header files in both the .cpp files.
Now I have an external header, say external.h. I included external.h in normal.h and abnormal.cpp.
But I am getting link errors. Kindly help me on how to include the external header file.
This is my normal.h code
#pragma once
#include<iostream>
#include<external.hpp>
class normal
{
public:
normal();
~normal();
void function();
void Function();
};
normal.cpp code
#include"normal.h"
normal::normal(){
}
normal::~normal(){
}
abnormal.cpp code
#include"normal.h"
#include<external.hpp>
void normal::function()
{
//external library's supported function call
}
Errors
Severity Code Description Project File Line Suppression State
Error LNK2005 "public: virtual void __cdecl
external::tools::Predicate_ite::reset(void)" (?reset#Predicate_ite#tools#aff3ct##UEAAXXZ) already defined in abnormal.obj trial3 F:\trial3\trial3\normal.obj 1
Error LNK2005 "public: virtual bool __cdecl
external::tools::Predicate_ite::operator()(void)" (??RPredicate_ite#tools#aff3ct##UEAA_NXZ) already defined in abnormal.obj trial3 F:\trial3\trial3\normal.obj 1
Error LNK2005 "public: __cdecl
external::tools::Predicate_ite::Predicate_ite(int)" (??0Predicate_ite#tools#aff3ct##QEAA#H#Z) already defined in abnormal.obj trial3 F:\trial3\trial3\normal.obj 1
Error LNK1169 one or more multiply defined symbols found trial3 F:\trial3\x64\Release\trial3.dll 1
Including headers into more than one code file is not a prolem.
There is nothing abnormal about a second code file including the same header.
Linker problems might arise from doing one of the following:
including headers which contain code instead of only declarations, typedefs, macro definitions and implementations of templated classes
the same applies to including code files
including the same header more than once into the same code file (though that is not a problem in many cases); the adverse effect of this can be avoided with "header guards" also known as "reinclusion guards" (#ifndef HEADERNAME_H #define HEADERNAME_H /* content */ #endif /* HEADERNAME_H */ ), credits to David C. Ranking for bringing this up; a special case of this is to include the header twice by once including direclty and once indirectly via another header (which seems to be what you worry about)
Linker problems can also occur unrelated to header including, if the smybols are only declared but not defined, e.g. when the corresponding libraries are not correctly added to the project (thanks to Ted Lyngmo for bringing that up).
Other problems than linker problems might arise from:
includiong headers with conflicting/contradictory content
circular inclusions
unsolved dependencies caused by including headers in the wrong order which wrongly have a dependency on their order

LNK2005 already defined error on inclusion of C-type header file in C++ project [MSVC12]

I've hit a roadblock in attempting to integrate some third-party code in my project. I'm attempting to integrate fontstash, which is a header-only OpenGL text rendering solution. (https://github.com/memononen/fontstash) As a whole, I'm also using SDL, GLEW, AssImp, Lua 5.3/LuaBridge, and Bullet Physics. I've placed the fontstash header files in my vc/include directory. Compilation proceeds normally but linking fails miserably in a huge wall of...
c_main.obj : error LNK2005: "unsigned int __cdecl glfonsRGBA(unsigned char,unsigned char,unsigned char,unsigned char)" (?glfonsRGBA##YAIEEEE#Z) already defined...
c_main.obj : error LNK2005: "void __cdecl glfonsDelete(struct FONScontext *)" (?glfonsDelete##YAXPAUFONScontext###Z) already defined in...
...
c_main.obj : error LNK2005: _stbtt_FindMatchingFont already defined in...
c_main.obj : error LNK2005: _stbtt_GetFontNameString already defined...
It appears to simply iterate the entire list of functions provided via the fontstash header files. I've tried wrapping the headers in an extern "C" {} to no avail. I've tried including the files from the project directory as well. I'm at a loss as to why this would be happening and where to begin figuring out what would be causing it. As indicated in the topic title I'm using MSVC12/Win7, and I'm building for Windows and compiling for x86.
Additionally, I'm including the files more than once as the relevant code that utilizes fontstash is used in other locations. I've thought about this being the issue, but the provided header files from fontstash have inclusion guards so I fail to see why this would occur in that regard.
This is a common problem with the header files, that contain implementaton. When you use #include directive, compiler simply inserts .h file content instead of it. So when you use this header in different places of your project, you get several identical implementations of its methods and global variables. Since it has #ifdef or #pragma once compiler guard, it compiles just fine. But when linker is trying to unite all compiled obj files to one executable module, it gets several identical implementations. Since it could not know which one should be used, you get LNK2005 error. To solve this problem you could move implementations and globals into the separate cpp file and include it in the project. Other way would be to mark all header functions as inline, or use __declspec(selectany)

tracking down LNK2005: "already defined"

I have been working on a program in windows VC++ 2008. I started by having all of my code in .cpp files (just to get everything working), and now breaking things into .h, and .cpp files. when I compile I get a mountain of LNK2005 errors stating that:
Object.obj : error LNK2005: "__thiscall thing::thing(args)" already defined in otherObject.obj
while I was making the original program I kept getting errors of undeclared identifier, and so I gave a include directive to satisfy that. now when I am breaking everything up into separate .cpp, and .h files I get all of this. which place do I start looking (Object, otherObject, or thing), or somewhere else.
Basically you have definition for thing::thing(args) in two Translation Units(TU), which violates the One Definition Rule(ODR) and hence the error.
The linker exactly tells you which TU's are involved: otherObject.obj and Object.obj.
Start looking in to otherObject.cpp and Object.cpp and the headers which are included in these two cpp files. It is most likely that you have defined your constructor thing::thing(args) in header file and including that header file in both these cpp files results in multiple definitions.
Suggested Solution:
You cannot define the constructor in header file, You need to add it to your cpp file along with other member functions of the class. If you must add the definition of constructor to header you should mark it inline, given that You have not shown your code I don't see any reason to apply the second approach.
Given the information in your question, I bet that the method is defined in a header file but not marked inline. This then causes duplicate symbol linker errors. Try marking hte method inline or moving the definition to a source (.C) file.

Multiply defined structure error

I had a big main .cpp file with everything in it .I needed to break the code and so I created a helper.h where I moved all the typedefs, function declarations etc.Now I am trying to move some of the functions from main .cpp into helper.cpp .I had a global called mypoint* originalpoint[mypoint is a stucture I defined in helper.h].I moved it into helper.h and placed one of the functions that uses it into helper.cpp .It is throwing this error now :-
Error 1 error LNK2005: "struct mypoint * originalpoints" (?originalpoints##3PAUmypoint##A) already defined in Main.obj Helper.obj Stereo002
Error 2 fatal error LNK1169: one or more multiply defined symbols found C:\Documents and Settings\Raj\My Documents\Visual Studio 2008\Projects\Stereo002\Debug\Stereo002.exe 1 Stereo002
I am not sure why is it saying multiply defined.I have everything in helper.h .I include helper.h into main.cpp and helper.cpp.
You put the creation of a variable into the .h file, so it's being created in both .cpp files.
The way to fix this is to declare it as extern in the .h file, and duplicate it without the extern in one of the .cpps.
In this case, since your header is included in two places, the compiler will create an instance of that variable for each time it is included. When the linker runs next, it finds two definitions for 'originalpoint' and complains.
Mark's answer is correct - in order to work around this issue, you can specify the variable as having external linkage by declaring it 'extern', which tells the linker to look for the declaration of this variable elsewhere (in one of the cpp files). Then, you actually declare it in one of the cpp files.
It is worth confirming that this is indeed what you want - one variable shared between the two files. Since they were originally part of the same implementation file, this is probably the desired effect.