LNK2019 - Unresolved external symbol - c++

I've tried to find a solution to this problem by looking through the old questions and answers, but I can't spot what's wrong in my case. I get the following error:
Error 66 error LNK2019: unresolved external symbol "public: static class PhysicsBody *
__cdecl PhysicsBody::createBox(float,float,enum PhysicsBodyType,float)"
(?createBox#PhysicsBody##SAPAV1#MMW4PhysicsBodyType##M#Z) referenced in function
"public: __thiscall Enemy::Enemy(void)" (??0Enemy##QAE#XZ)
The weird thing is, the code file is there, both .H and .CPP, and they are included in the solution and compiled correctly. Here's the code files:
// Enemy.h
#pragma once
class Enemy {
public:
Enemy();
private:
PhysicsBody* m_body;
};
// Enemy.cpp
#include "Enemy.h"
#include "PhysicsBody.h"
Enemy::Enemy() {
m_body = PhysicsBody::createBox(1.f, 1.f, PhysicsBodyType::Dynamic);
}
// PhysicsBody.h
#pragma once
enum PhysicsBodyType {
Static, Dynamic, Kinematic
};
class PhysicsBody {
public:
static PhysicsBody* createBox(float width, float height, PhysicsBodyType type, float mass = 1.f);
private:
PhysicsBody();
};
// PhysicsBody.cpp
#include "PhysicsBody.h"
PhysicsBody::PhysicsBody() {
}
PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
return new PhysicsBody();
}
(I have cropped out some non-relevant code here.)
I've literally skimmed through the code tens of times and cannot spot anything wrong with it. I have similar code throughout my project and everything else works. For some reason, this PhysicsBody class causes these problems. I've checked that it's included in the project / solution, the file type is C/C++ Code, it's not marked as content and overall it should be working.

The problem was quite probably caused by a faulty VS project file. I copied the contents of PhysicsBody.h / .cpp files, deleted both files, created new files and pasted the original contents. All code is exactly the same and it works now, so I conclude that it's a VS-related bug.

Bug in the code in the question
The function that is not found is:
PhysicsBody::createBox(float, float, enum PhysicsBodyType, float)
The function that is shown as defined is:
PhysicsBody::createBox(float, float, enum PhysicsBodyType)
There's a different number of arguments between the two functions.
Questions arising:
Which is the correct definition?
How did the erroneous definition get used?
Where was the declaration for the erroneous use?
You may need to simply recompile everything. You may need to look at where your PhysicsBody class is defined because it is defined in two places.
This problem has now been fixed in the question.
No significant bug in the code in the question
With the code as in the amended question (with #include "PhysicsBody.h" added at the start of Enemy.h so the header can be compiled standalone), and ignoring warnings about the unused parameters to the createBox function, I can compile and link the code using g++ from GCC 4.9.1 and a trivial main():
#include "Enemy.h"
int main()
{
Enemy e;
return 0;
}
That suggests to me that the problem is not in the code you show but rather the problem is in the code you don't show. Please study how to create a MCVE (How to create a Minimal, Complete, and Verifiable Example?) or
SSCCE (Short, Self-Contained, Correct Example) — two names and links for the same basic idea.
Please post exactly the minimal code that reproduces the problem. (I created a new subdirectory, placed 5 source files — two headers, two implementation files and a trivial main() — into the directory, and a makefile and compiled from there. I suggest you do the equivalent on your Windows machine.)
If you affirm that the code posted above plus the main.cpp I show does (1) compile and (2) fail to link, thus reproducing the problem, then there is superficially a bug in MSVC. I think that's unlikely to be the case, but funnier things have been known.
For the record, I was compiling on Mac OS X 10.9.4 Mavericks with GCC 4.9.1 and the following commands (with warning messages shown):
$ g++ -O3 -g -std=c++11 -Wall -Wextra -c Enemy.cpp
$ g++ -O3 -g -std=c++11 -Wall -Wextra -c PhysicsBody.cpp
PhysicsBody.cpp:8:43: warning: unused parameter ‘width’ [-Wunused-parameter]
PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
^
PhysicsBody.cpp:8:56: warning: unused parameter ‘height’ [-Wunused-parameter]
PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
^
PhysicsBody.cpp:8:80: warning: unused parameter ‘type’ [-Wunused-parameter]
PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
^
PhysicsBody.cpp:8:92: warning: unused parameter ‘mass’ [-Wunused-parameter]
PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
^
$ g++ -O3 -g -std=c++11 -Wall -Wextra -c main.cpp
$ g++ -o main *.o
$ ./main
$ echo $?
0
$

Related

gcc linking externs incorrectly?

I'm relatively new to gcc and I'm using 'gcc (tdm-1) 5.1.0'. I've come across a very peculiar circumstance by mistake. I've shrunk my concern down to a very small reproducible example...
main.cpp
extern int g;
int main(){
return g;
}
someOtherFile.cpp
#include<windows.h>
RECT g;
this I compile with
gcc -c someOtherFile.cpp
gcc main.cpp someOtherFile.o
and this will link without error.
Am I missing something here as to why this is allowed to link?
3.5/10:
After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound (8.3.4). A violation of this rule on type identity does not require a diagnostic.
That last sentence means the compiler and linker are not required to give you an error message. It's your job to get it straight.
In C++ it won't link as the types of g are non-matching between main.cpp and someOtherFile.cpp. You have to have int g in someOtherFile.cpp or opposite, extern RECT g; in main.cpp.
In C this will compile and link, but on in c++.
Com compile and link as c++:
g++ -c someOtherFile.cpp
g++ -c main.cpp
g++ main.o someOtherFile.o -o test
Alternatively, you may use functions for this:
main.cpp
int g();
int main{
return g();
}
someOtherFile.cpp
#include<windows.h>
RECT r;
int g()
{
return (int)r;
}
Obviously not recommended (as there isn't much point to cast RECT to int), but that would be similar in effect to what you were trying to do.
Variable g inside someOtherFile.cpp isn't related to the other extern int g declared in main.cpp. In effect, the int g simply isn't defined anywhere and linker will fail at the end for this reason.
Apparently, this will actually compile and link by g++, while microsoft linker will error on this type of mistake.

Undefined refence to 'vtable for Adafruit_GFX' due cross compiling raspberry pi

In Visualstudio by trying to cross compile to a raspberry pi, I get the following error:
VisualGDB: Run "make CONFIG=Debug" in directory "/tmp/VisualGDB/c/Users/Revius/Desktop/usbtest/conversiecsc++/LinuxProject12/LinuxProject12" on pi#raspberrypi (SSH)
g++ -ggdb -ffunction-sections -O0 -DDEBUG -c LinuxProject12.cpp -o Debug/LinuxProject12.o -MD -MF Debug/LinuxProject12.dep
g++ -o Debug/LinuxProject12 -Wl,-gc-sections -L/home/pi/libssd1306/build/ArduiPi_OLED -Wl,--start-group Debug/LinuxProject12.o -Wl,--rpath='$ORIGIN' -Wl,--end-group
Debug/LinuxProject12.o: In function `Adafruit_GFX::~Adafruit_GFX()':
C:\Users\Revius\AppData\Local\VisualGDB\RemoteSourceCache\raspberrypi\0003\include\Adafruit_GFX.h(35): error VGDB1000: undefined reference to `vtable for Adafruit_GFX'
The part off Adafruit_GFX.H where the compiler is pointing to is
"virtual ~Adafruit_GFX() {};"
in:
#ifndef _ADAFRUIT_GFX_H
#define _ADAFRUIT_GFX_H
#define swap(a, b) { int16_t t = a; a = b; b = t; }
//class Adafruit_GFX : public Print {
class Adafruit_GFX {
public:
//Adafruit_GFX();
// i have no idea why we have to formally call the constructor. kinda sux
void constructor(int16_t w, int16_t h);
virtual ~Adafruit_GFX() {};
// this must be defined by the subclass
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
virtual void invertDisplay(boolean i);
The weird part is that I use "make" on the raspberry pi and in works, I can start so it works the code is alright? But not by Visualstudio?
So my question is:
Due I am cross compilling could i be the compiler is missing some file or are there options i could manipulate to get it working?
In which direction do I have to look to find the answer?
Setting for the Makefile in MSVS-GDB for oled display
By adjusting (or correct filling in te settings) i got it working.

gcc/g++ internal error (c++ templated lambda)

i was just making a few changes to my program, when all of a sudden g++ complained with an internal compiler error.
Clang however compiles it without any problems and also does not give any warnings, that would indicate anything weird.
I distilled the problem down to this:
#include <functional>
template<typename T>
class A{
T someVar;
};
template<typename T>
class B {
int x;
std::function<A<double>(A<int>&)> someLambda = [&](A<int>& aInt){
int xVar = x;
A<double> aRet;
return aRet;
};
};
int main(int argc, char** argv){
B<int> a;
return 0;
}
I tried both GCC 4.9.2 and 4.8.4, with both failing (internal compiler error).
Flags I used:
g++ -std=c++11 -O0 -g -Wall main.cpp -o gccBin
clang++ -std=c++11 -O0 -g -Wall main.cpp -o clangBin
main.cpp: In instantiation of 'struct B<int>::<lambda(class A<int>&)>':
main.cpp:10:7: required from here
main.cpp:14:24: internal compiler error: in tsubst_copy, at cp/pt.c:12569
int xVar = x;
^
libbacktrace could not find executable to open
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
Clang++(3.5.1) compiles it without a problem, as I mentioned.
I also tried multiple machines, everywhere the same.
Is there some kind of error I overlooked? I searched a bit on the internet and the only similar problems i could find should have been fixed by now (as the bugtracker states).
Could maybe someone try and run this code on their machine or give other advice?
Thank you,
Lazarus
It's a compiler bug. Just go ahead and file a bug report to the GCC dudes!

How do I turn off compiler warnings tagged with [enabled by default] in Code Blocks

I am trying to use constants in a class which should be okay in c++11 but I get this warning:
warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
The problem is that I get this many (more than 10) times for every constant I declare. This effectively fills the build messages and makes any other compiler warnings impossible to find.
I would like to make it so this no longer shows up in my build messages box.
I know people like to see relevant code so here it is:
class GameState: public State
{
public:
const Uint8 * keyStates;
Point gameMousePos;
int UIType;
std::vector<UI *> UIs;
Texture * lockingTex;
HitBox * inGame;
const int buttonDim = 100;
const int buttonOffY = 70;//distance from bottom
const int buttonOffX = 130;//distance from each other
const int buttonTextOffY = 140;//text distance from bottom
bool locking;
bool noPlaceBool;
float gameSpaceScale;
HitBox * gameSpace;
Texture * bkg;
float windowRotSpeed;
float inHandRotSpeed;
float windowMoveSpeed;
GameState();
void handle_events();
void logic();
void render();
void save();
void load_save();
}
The compiler warning tells you exactly what to do:
warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
By default g++ uses C++03.
To activate C++11 features you need to tell the compiler to use C++11
g++ -std=c++11 stuff.cpp
Once you are using C++11 the default features ("enabled by default") for that language will be enabled.
The compiler is telling you that it should be static:
warning: non-static data member ...
So if you were to add the static keyword, it would solve your problem.
So change these:
const int buttonDim = 100;
With:
static const int buttonDim = 100;
And the warnings should go.
Note that was part of C++ for a very long time (only cl [Microsoft compiler] did not support it well before 2008 or so.)
As a side note, a good programmer wants to do the opposite: transform all warnings to errors to be forced to fix all warnings. I very rarely have to go around a warning and it is always rather edgy cases (like compare two floating point numbers with == or !=. So all of that to say, I would actually advice you use -Werror and always find the exact reason for a warning.
Of course, if you are working with someone else code... that's a different story. They may not want to fix their code.

"Cross-compatible" code spits errors in linux and compiles fine on windows! (GLM)

I'm really surprised, today I downloaded Ubuntu 12 LTS 32bit and installed build essential.
Then I created a makefile for my project which I just copy pasted from another project from the internet and edited a bit to enable C++11 stuff if it's needed for GLM stuff?
anyway the makefile:
GPP = g++
GCC = gcc
plugin_OUTFILE = "./QuaternionStuff.so"
COMPILE_FLAGS = -std=c++0x -m32 -O3 -fPIC -c -I ./ -w -D LINUX -D PROJECT_NAME=\"plugin\"
plugin = -D plugin $(COMPILE_FLAGS)
all: plugin
clean:
-rm -f *~ *.o *.so
plugin: clean
$(GPP) $(plugin) ./*.cpp
$(GPP) -std=c++0x -m32 --static -fshort-wchar -shared -o $(plugin_OUTFILE) *.o
now, when I run it, linux spits there errors out and I seriously don't understand them..
Now, the code works on windows, compiles fine with highest warning level etc, and it's good!
But the g++ program is somewhat not happy with this:
no matching function for call to ‘GetPitchYawBetweenCoords(glm::vec3, glm::vec3, glm::vec2&)’
note: glm::vec2 GetPitchYawBetweenCoords(glm::vec3&, glm::vec3&)
note: candidate expects 2 arguments, 3 provided
//prototypes:
inline glm::vec2 GetPitchYawBetweenCoords(glm::vec3 &source, glm::vec3 &target);
inline void GetPitchYawBetweenCoords(glm::vec3 &source, glm::vec3 &target, glm::vec2 &output);
And the code, with the according functions which calls it:
//the call
inline void AmxSetVector3(AMX * amx, cell * &params, unsigned char startpos, glm::vec3 vector)
{
//some code here
}
inline void AmxSetVector2Inverse(AMX * amx, cell * &params, unsigned char startpos, glm::vec2 vector)
{
//some code here
}
static cell AMX_NATIVE_CALL GetPitchYawBetweenPositions( AMX* amx, cell* params )
{
glm::vec2 rot;
GetPitchYawBetweenCoords(AmxGetVector3(params,1),AmxGetVector3(params,4),rot);
AmxSetVector2Inverse(amx,params,7,rot);
return 1;
}
How the hell can it not distinguishsuch two very different functions (prototypes)?
This is the most confusing part of all the errors, but there is more :(
I don't see anything that is wrong with that.
So, what I do is: I change (with big pain, because now my code gets quircky because I need to change everything just for the linux distirbution) the functions to different names, I just added an 'R' to the end of the second prototype, but then another ton of errors come up..
In function ‘cell SomeFunction(AMX*, cell*)’:
error: invalid initialization of non-const reference of type ‘glm::vec3&
{aka glm::detail::tvec3<float>&}’ from an rvalue of type ‘glm::detail::tvec3<float>’
and that's again.. on the same function...:
static cell AMX_NATIVE_CALL GetPitchYawBetweenPositions( AMX* amx, cell* params )
{
glm::vec2 rot;
GetPitchYawBetweenCoords(AmxGetVector3(params,1),AmxGetVector3(params,4),rot);
AmxSetVector2Inverse(amx,params,7,rot);//HERE
return 1;
}
What is going on? I have no idea how to fix this..
The G++ version is 4.6
Apparently, AmxGetVector3 returns a glm::detail::tvec3<float>.
According to the standard, this temporary object can't be bound to a non-const reference (this is what the second message is trying to tell you).
Unfortunately, Visual C++ has a silly non-standard extension, enabled by default, that allows that kind of binding.
Change your functions to have these (const-correct) prototypes:
inline glm::vec2 GetPitchYawBetweenCoords(const glm::vec3 &source, const glm::vec3 &target);
inline void GetPitchYawBetweenCoords(const glm::vec3 &source, const glm::vec3 &target, glm::vec2 &output);