Undefined reference C++
Asked Answered
R

2

16

I'm trying to compile my first legit program that I'm converting from Java (I ran a test hello world type program to check my compiler and it works). There are three files:

main.cpp

#include <iostream>
#include "skewNormal.h"

using namespace std;

double getSkewNormal(double, double);

int main(int argc, char **argv) {
    cout << getSkewNormal(10.0, 0.5) << endl;
}

skewNormal.cpp

#define _USE_MATH_DEFINES
#include <iostream>
#include <math.h>

using namespace std;

#include <skewNormal.h>

double SkewNormalEvalutatable::evaluate(double x)
{
    return 1 / sqrt(2 * M_PI) * pow(M_E, -x * x / 2);
}

SkewNormalEvalutatable::SkewNormalEvalutatable()
{
}

double sum (double start, double stop,
                               double stepSize,
                               Evaluatable evalObj)
{
  double sum = 0.0, current = start;
  while (current <= stop) {
    sum += evalObj.evaluate(current);
    current += stepSize;
  }
  return(sum);
}

double integrate (double start, double stop,
                                     int numSteps,
                                     Evaluatable evalObj)
{
  double stepSize = (stop - start) / (double)numSteps;
  start = start + stepSize / 2.0;
  return (stepSize * sum(start, stop, stepSize, evalObj));
}

double getSkewNormal(double skewValue, double x)
{
  SkewNormalEvalutatable e;
  return 2 / sqrt(2 * M_PI) * pow(M_E, -x * x / 2) * integrate(-1000, skewValue * x, 10000, e);
}

skewNormal.h

#ifndef SKEWNORMAL_H_INCLUDED
#define SKEWNORMAL_H_INCLUDED

class Evaluatable {
public:
  virtual double evaluate(double x);
};

class SkewNormalEvalutatable : Evaluatable{
public:
  SkewNormalEvalutatable();
  double evaluate(double x);
};

double getSkewNormal(double skewValue, double x);

double integrate (double start, double stop, int numSteps, Evaluatable evalObj);

double sum (double start, double stop, double stepSize, Evaluatable evalObj);

#endif // SKEWNORMAL_H_INCLUDED

Compiling yielded the following error:

main.cpp:9: undefined reference to `getSkewNormal(double, double)'

I'm using Code::Blocks on Ubuntu 10.10.

Replevy answered 8/6, 2011 at 20:16 Comment(12)
What's the compiler command that you're running?Ann
@Kerrek SB: He's using and IDE and it should already take care of linking everything.Singlecross
Hm, hard to tell, but the error looks like a linker, not compiler error. Try this: g++ -o prog main.cpp skewNormal.cpp, just to be sure.Ann
@delnan, I use an IDE, but I still have to tell it what's in my project...Dermatogen
@Roddy: I'm assuming OP has these files in one project. Granted, I've seen enough beginners getting tripped up by the UI myself and editing files that don't belong to a project, but OP supposedly already has some programming expreience.Singlecross
@Somanayr - For your info - Only standard headers are enclosed in <>. In skewNormal.cpp, the including header should be #include "skewNormal.h". ( i.e., user defined header included files should be enclosed in " " ). BTW, what you got is not a compilation error but it is a linker error.Phallus
Is the code you've provided copy-pasted from the original? Is the error in compiling or linking? It looks like a compiler error to me, but I can't see any reason for it.Murrey
I'm 99% sure I've got it right. I'm not a total noob :P I've done quite a bit in Java. I'll upload a screenie, one sec.Replevy
i701.photobucket.com/albums/ww19/Somanayr/Screenshot-2.pngReplevy
@Somanayr, Yup, it seems to be in the project. But it sounds like it's not being compiled/linked for some reason. Do you get a log of al the command-line actions when you do a clean build?Dermatogen
Mark's solution was correct. I told the compiler to build, but not where to put it. It just didn't build.Replevy
#include "skewNormal.h" should come before using namespace std;, in case that using declaration would have an effect on something in the header.Grig
F
21

You may be compiling skewNormal.cpp to a .o file, but you're not including it when you compile main.cpp.

Ferdelance answered 8/6, 2011 at 20:23 Comment(3)
Explain more? I see a /obj/Debug/main.o but no skewNormal.o. No other *.o files in sight.Replevy
@Somanayr, that means you're not even compiling sknewNormal.cpp at all. You need to fix that.Ferdelance
Aha. Thanks :D It was set to build, but there was no where to build to. What I mean by that is that it gave a list of places to put the build files into and I had selected none of them! Silly me. Thanks for the help!Replevy
G
1

Not sure if this is the problem, but it appears you're prototyping the function twice.

The double getSkewNormal(double skewValue, double x); line need only be in the header, not in main.cpp as well (since main.cpp includes skewNormal.h). Having it appear twice in a prototype form seems likely to confuse the compiler. You only need it to be visible to the code once, and usually that should be in a header (not a code file).

Try removing that line from main.cpp and recompile. :)

Gillispie answered 8/6, 2011 at 20:20 Comment(3)
I tried that. I actually had it out at first but added it in to see if it would change anything. Tried again and it still doesn't work: pastie.org/private/wt2oyt9v6pffcymuenabwwReplevy
Do you have all 3 files in the same project and are you compiling both cpp files? What error is given when you change it?Gillispie
Given that the error message there (the full error) is referencing the .o file, Mark's answer is likely your solution.Gillispie

© 2022 - 2024 — McMap. All rights reserved.