manabreak
manabreak

Reputation: 5597

LNK2019 - Unresolved external symbol

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.

Upvotes: 0

Views: 749

Answers (2)

manabreak
manabreak

Reputation: 5597

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.

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 755064

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:

  1. Which is the correct definition?
  2. How did the erroneous definition get used?
  3. 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
$

Upvotes: 0

Related Questions