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.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Ryan Amos
  • 5,422
  • 4
  • 36
  • 56
  • What's the compiler command that you're running? – Kerrek SB Jun 08 '11 at 20:20
  • @Kerrek SB: He's using and IDE and it should already take care of linking everything. –  Jun 08 '11 at 20:20
  • 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. – Kerrek SB Jun 08 '11 at 20:24
  • @delnan, I use an IDE, but I still have to tell it what's in my project... – Roddy Jun 08 '11 at 20:25
  • @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. –  Jun 08 '11 at 20:28
  • 3
    @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**. – Mahesh Jun 08 '11 at 20:28
  • 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. – David Thornley Jun 08 '11 at 20:29
  • 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. – Ryan Amos Jun 08 '11 at 20:31
  • http://i701.photobucket.com/albums/ww19/Somanayr/Screenshot-2.png – Ryan Amos Jun 08 '11 at 20:33
  • @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? – Roddy Jun 08 '11 at 20:37
  • Mark's solution was correct. I told the compiler to build, but not where to put it. It just didn't build. – Ryan Amos Jun 08 '11 at 21:15
  • `#include "skewNormal.h"` should come before `using namespace std;`, in case that using declaration would have an effect on something in the header. – M.M Jul 09 '15 at 02:59

2 Answers2

21

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

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Explain more? I see a /obj/Debug/main.o but no skewNormal.o. No other *.o files in sight. – Ryan Amos Jun 08 '11 at 20:27
  • 2
    @Somanayr, that means you're not even compiling sknewNormal.cpp at all. You need to fix that. – Mark Ransom Jun 08 '11 at 20:28
  • 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! – Ryan Amos Jun 08 '11 at 20:35
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. :)

ssube
  • 47,010
  • 7
  • 103
  • 140
  • 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: http://pastie.org/private/wt2oyt9v6pffcymuenabww – Ryan Amos Jun 08 '11 at 20:24
  • 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? – ssube Jun 08 '11 at 20:26
  • Given that the error message there (the full error) is referencing the .o file, Mark's answer is likely your solution. – ssube Jun 08 '11 at 20:32