Undefined reference, leak I can't get my head around.

Someone posed an assignment question on beginners forum which I thought I'd have a go at. For some reason my class file compiles fine, but when I try to make the executable with main() it complains of an :
undefined reference to gotInteger(basic_istream<char, char_traits<char> >&, int&)
collect2, ld returned status 1

I don't understand why the object file compiles fine but the executable won't. Makes no sense to me.'code is as follows.

procint.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include "procint.h"

procint::procint(string input)
{
   // TODO: initialize.
   setInputFile(input);
}
procint::~procint()
{
   // TODO: de-initialize.
}
void procint::setInputFile(string infl)
{
   inFile=infl;
}
string procint::getInputFile()
{
   return inFile;
}
void procint::processFile()
{
   // TODO: open file.
   ifstream theFile(getInputFile().c_str());
   if (! theFile.is_open())
   {
      cerr << "Unable to open: " << getInputFile()
         << endl;
      cerr << "Check file exists, and has permissions"
         << endl;
      exit (1);
   }
	
   // TODO: process file.
   int i;
   int count=0;

    // will change this to (gotInteger(theFile, i))
   while (gotInteger(cin, i))
   {
       myArray[count++] << i;
   }

}
bool gotInteger(istream& is, int& i)
{ 
   char c;
   cout << endl;
   while (true)
   {
      is >> i;
      if (is.good()) return true;
      if (is.eof()) return false;
      if (is.bad()) return false;
      // must clear junk
      is.clear();
      is >> c; // clears bad char.
      cout << "Bad int=[ " << c << " ]" << endl;
   } 
}
void procint::sortArray()
{
   // TODO: implement some nice sorting algorithms.
} 



procint.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Simple program to process a file
// full of integers.

#ifndef PROCINT_H_
#define PROCINT_H_

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::cerr;
using std::istream;

#include <string>
using std::string;

#include <cstdlib>
using std::exit;

#include <fstream>
using std::ifstream;

class procint
{
  public:
    procint(string input);
    ~procint();
    void setInputFile(string infl);
    string getInputFile();
    void processFile();
    bool gotInteger(istream& is, int& i);
    void sortArray();

  private:
    // change depending on file size.
    const static int ARRSIZE=100;
    int myArray[ARRSIZE];
    string inFile;
};

#endif 


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//.. procint:
// process integers in file.
// read to array then sort.

#include "procint.h"

int main(int argc,char *argv[])
{
   string insw="-i";
   string filename="";

   if (argc=2)
      filename=argv[i];
   else
   {
      cerr << "Usage: input_filename" << endl;
      exit (1);
   }

   if (filename=="")
   {
      cerr << "Must include filename" << endl;
      cerr << "Usage: input_filename" << endl;
      exit (1);
   }
   else
   {
      procint pi(filename);
      pi.processFile();
   }
}
Last edited on
commenting out the lines:
while (gotInteger(theFile, i))
{
myArray[count++] << i;
}
it compiles fine. :s I don't get it, something wrong with my logic?
I dont find procint::gotInteger anywhere in procint.cpp file.
closed account (1yR4jE8b)
Exactly,

you have

bool gotInteger(istream& is, int& i)

but it should be

bool procint::gotInteger
wow that's strange, not that I missed it but.... why did it compile when I took out the small while loop in processFile?

Compiler should have said: line... is of non class type procint(std::string char_traits blah blah)
Last edited on
Because the compiler and the linker allow declared but undefined functions as long as there are no calls to them and no one tries to get their address.

By the way, I see no reason for gotInteger() to be a member function. There are no references to this anywhere in that function.
Last edited on
line 38 procint.cpp

i use it in the while loop to return a bool. true if int and valid. otherwise will print out bad char.

I thought undefined reference, was something about undeclared variable, at least I won't make that mistake again thanks. ( i hope )
Last edited on
Yes, but the function itself doesn't use this. It's the equivalent of this:
1
2
3
void f(std::string foo){
    std::cout <<"bar";
}

Does that function make sense? It's taking a parameter it doesn't use.
correct, it's not using foo....

but is my function not using istream and int the way I think it is?
is >> i ;

should I rename the int or just use this? it's not as if it's a class member.
Last edited on
the way i see it is, istream& is, int& t are being passed by reference, whereas the values I pass them from processFile(), only exist within the scope of processFile() so why would I need to use this keyword?
Last edited on
bump
Exactly. Why is a member function if you don't ever use this?
edit:
The keyword this:

The keyword this represents a pointer to the object whose member function is being executed. It is a pointer to the object itself.

One of its uses can be to check if a parameter passed to a member function is the object itself.
It is also frequently used in operator= member functions that return objects by reference (avoiding the use of temporary objects).
1
2
3
4
5
6
CVector& CVector::operator= (const CVector& param)
{
  x=param.x;
  y=param.y;
  return *this;
}

In fact this function is very similar to the code that the compiler generates implicitly for this class if we do not include an operator= member function to copy objects of this class.



I would have thought going by that last comment in the tutorial, that it is done anyway. and being that I am only returning true or false... there's no point using keyword this.

Additionally I don't understand why you are both implying member functions need this does that mean my constructor, my sort, and processFile all my sets and gets all need to use this as well?
What is so different about this function compared to others?
Last edited on
What we're trying to say is that there's no point in procint::gotInteger() being a member function. If you were to remove the procint:: from the definition and remove the declaration from the class definition, the program would still compile. When that happens it's because the function doesn't make neither implicit nor explicit use of the this pointer, which means the function shouldn't be member of a class.

See this example:
1
2
3
4
5
6
7
8
9
struct A{
    int a;
    void f1(){
        a++; //(implicitly: this->a++;)
    }
    int f2(){
        return rand();
    }
};

A::f2() shouldn't be a member of A because it doesn't use this implicitly or explicitly. You're passing a useless parameter to call it:
1
2
3
4
A o;
o.a=0;
o.f1(); //o is passed as this
o.f2(); //o is passed as this, even though f2() doesn't need it 

Obviously, this isn't a performance problem. Passing a pointer is almost insignificant. Instead, it's a design problem. You're putting interfaces where they don't belong.
What we're trying to say is that there's no point in procint::gotInteger() being a member function. If you were to remove the procint:: from the definition and remove the declaration from the class definition, the program would still compile.

I don't think it would unless I removed or changed the while loop as well.
A::f2() shouldn't be a member of A because it doesn't use this implicitly or explicitly. You're passing a useless parameter to call it:

I still don't understand how what I'm doing is considered useless...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

//  i call gotInteger using cin, i
//  istream& is, is a reference to cin.  (where 'cin' buffer exists in memory)
//  int& i, is a reference to i (where 'i' exists in memory)
bool procint::gotInteger(istream& is, int& i)
{
//  this function:
//  if an integer could be extracted then
//  true is returned and so is the integer   
//  otherwise
//  false is returned and no integer is returned
//  This routine consumes and discards non-integer chars,
//  hence it changes the state of the stream by always moving
   char c;
   while (true)
   {
      is >> i;  // cin >> i
      if (is.good()) return true;
      if (is.eof()) return false;
      if (is.bad()) return false;
      // must clear junk
      is.clear();
      is >> c; // clears bad char.
      cout << "Bad int=[ " << c << " ]" << endl;
   } 


-----------------
Obviously, this isn't a performance problem. Passing a pointer is almost insignificant. Instead, it's a design problem. You're putting interfaces where they don't belong.


I guess the reason I don't understand is the confusion between this and this in java. I can't really see where this in C++ would be that useful. Whereas in java I use it constantly because it points to the class fields, hence is used in most acsessors. Also I still don't fully grasp why you use it in C++.

Don't worry about it though you have explained it enough, yet I still don't seem to grasp it, so I can put it off for a week or two and come back to it. If I still need further clarification then I will ask in a different post.
i think perhaps the main reason I don't quite get it is your samples make sense, however I can't see the relevance between my method and your samples.
Thanks for your help guys.
member functions do something with or to an object.

IE:

1
2
3
MyClass foo;

foo.Bar();


With that code, since Bar is a member function, its assumed that 'foo' (ie, 'this') is used in some way.

In your gotInteger function, 'this' is never used. And it therefore makes little sense for the function to be a nonstatic member.

For organizational purposes, it might make sense to make it a static member.
so am I supposed to say this.is >> this.i ;
or return this.true
return this.false.

It's a very simple program I don't see the harm in having a utility in my class obj.
Last edited on
I think I get where your comming from, so your saying if I had of simply used this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
using std::cin;
using std::cout;
using std::istream;

#include <string>
using std::string;
             
bool gotInteger(istream& is, int& i);

////////////////////////////

int main()
{
   cout << "Enter words intermixed with integers ... EOF stop\n";

   int i;

   while (gotInteger(cin, i))
      cout << i << '\n';

}
//Purpose: extract and return integer from an input stream
bool gotInteger(istream& is, int& i)
{
   char c;

   while(true)
   {
      is >> i;
      if (is.good()) return true;
      if (is.eof()) return false;
      if (is.bad()) return false;
      // 
      is.clear();
      is >> c; 
   }
}


it's not a class, it's just a program that does random things, so it's fine....???
Last edited on
Topic archived. No new replies allowed.