Discussion:
C++ linker error after overloading an operator
(too old to reply)
m***@gmail.com
2017-01-20 12:47:58 UTC
Permalink
I keep getting the following error when I try to compile an example program from C++ how to program, Deitel and Deitel. I used
g++ Fig11_05.cpp -o Fig11_05

I spent hours trying to solve this problem by looking up the Internet and particularly stackoverflow, but with no avail!

I tried using different command line arguments such as -libstd=libc++, -std=c++11, -std=c++14

the error I keep getting is as this:

Undefined symbols for architecture x86_64: "operator<<(std::__1::basic_ostream >&, PhoneNumber const&)", referenced from: _main in Fig11_05-1f04bd.o "operator>>(std::__1::basic_istream >&, PhoneNumber&)", referenced from: _main in Fig11_05-1f04bd.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

The result of g++ -v:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/c++/4.2.1 Apple LLVM version 8.0.0 (clang-800.0.42.1) Target: x86_64-apple-darwin15.6.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

The codes:

// Fig. 11.3: //PhoneNumber.h
// PhoneNumber class //definition
#ifndef PHONENUMBER_H
#define PHONENUMBER_H

#include <iostream>
#include <string>


class PhoneNumber
{
friend std::ostream& operator<<(std::ostream&, const PhoneNumber&);
friend std::istream &operator>>(std::istream&, PhoneNumber&);
private:
std::string areaCode; // 3-digit area //code
std::string exchange; // 3-digit //exchange
std::string line; // 4-digit //line
}; // end class //PhoneNumber

#endif

// Fig. 11.4: PhoneNumber.cpp
// Overloaded stream insertion and stream extraction //operators
// for class //PhoneNumber.
#include <iomanip>
#include "PhoneNumber.h"
using namespace std;

// overloaded stream insertion operator; cannot //be
// a member function if we would like to invoke it //with
// cout << //somePhoneNumber;
ostream& operator<<(ostream& output, const PhoneNumber& number)
{
output << "Area Code: " << number.areaCode << "\nExchange: "
<< number.exchange << "\nLine: " << number.line << "\n"
<< "(" << number.areaCode << ") " << number.exchange << "-"
<< number.line << "\n";;
return output; // enables cout << a << b << //c;
} // end function //operator<<

// overloaded stream extraction operator; cannot //be
// a member function if we would like to invoke it //with
// cin >> //somePhoneNumber;
istream& operator>>(istream& input, PhoneNumber& number)
{
input.ignore(); // skip (
input >> setw(3) >> number.areaCode; // input area //code
input.ignore(2); // skip ) and //space
input >> setw(3) >> number.exchange; // input //exchange
input.ignore(); // skip dash //(-)
input >> setw(4) >> number.line; // input //line
return input; // enables cin >> a >> b >> //c;
} // end function operator>>


// Fig. 11.5: //fig11_05.cpp
// Demonstrating class PhoneNumber's overloaded stream //insertion
// and stream extraction //operators.
#include <iostream>
#include "PhoneNumber.h"
using namespace std;

int main()
{
PhoneNumber phone; // create object //phone

cout << "Enter phone number in the form (123) 456-7890:" << endl;

// cin >> phone invokes operator>> by implicitly //issuing
// the global function call operator>>( cin, phone //)
cin >> phone;

cout << "\nThe phone number entered was:\n";

// cout << phone invokes operator<< by implicitly //issuing
// the global function call operator<<( cout, phone //)
cout << phone << endl;
} // end main

Note: I recently installed then uninstalled CUDA toolkit 8. I needed a newer version of Xcode, so I installed Xcode the newest version 8.2.1, and kept the old version in a different directory just in case. I don't think the problem is with the installation of Xcode though. Also when I installed CUDA I had to set DYLD_LIBRARY_PATH to a directory. However, it might not be the source of the problem! I am just trying to help you figure out the problem to help me fix it :)

Thank you in advance!
Geoff
2017-01-21 03:29:12 UTC
Permalink
That's certainly some messy C++. Lots of extra // in the comments for
some reason.

I recommend if you are going to write multi-line comments that you use
the /* */ delimiters instead of the one-line version. If you use //
then limit your lines to 70 characters and use the delimiter only once
per line.

As to your error, it's not from Xcode 8.2.1 in it's default
configuration. After cleaning up the posted code comments I was not
able to duplicate your problem and the code compiled and linked
correctly in Xcode.

I compiled it from the command line with:
g++ -m64 PhoneNumber.cpp fig11_04.cpp

I seem to recall on OS X Maverick needed to have the x86/x86_64
libraries rebuilt or configured for command line tools but I don't
remember the procedure off-hand.
m***@gmail.com
2017-01-21 09:19:24 UTC
Permalink
Post by Geoff
That's certainly some messy C++. Lots of extra // in the comments for
some reason.
I recommend if you are going to write multi-line comments that you use
the /* */ delimiters instead of the one-line version. If you use //
then limit your lines to 70 characters and use the delimiter only once
per line.
As to your error, it's not from Xcode 8.2.1 in it's default
configuration. After cleaning up the posted code comments I was not
able to duplicate your problem and the code compiled and linked
correctly in Xcode.
g++ -m64 PhoneNumber.cpp fig11_04.cpp
I seem to recall on OS X Maverick needed to have the x86/x86_64
libraries rebuilt or configured for command line tools but I don't
remember the procedure off-hand.
Thank you for replying. You are right there are lots of commented lines. As I said to Alf, the problem was I didn't not think that we needed to link all *.cpp files. I used g++ Fig11_04.cpp -o Fig without linking the other c++ file. I should've used this g++ Fig11_04.cpp PhoneNumber.cpp -o Fig. In java you would compile all java files as javac *.java then run only the file with the main thread as java <file_name>, so I thought in c++ we only needed g++ Fig11_04.cpp -o Fig since Fig11_04.cpp is the only one with the main.
Geoff
2017-01-21 09:50:15 UTC
Permalink
Post by m***@gmail.com
Post by Geoff
That's certainly some messy C++. Lots of extra // in the comments for
some reason.
I recommend if you are going to write multi-line comments that you use
the /* */ delimiters instead of the one-line version. If you use //
then limit your lines to 70 characters and use the delimiter only once
per line.
As to your error, it's not from Xcode 8.2.1 in it's default
configuration. After cleaning up the posted code comments I was not
able to duplicate your problem and the code compiled and linked
correctly in Xcode.
g++ -m64 PhoneNumber.cpp fig11_04.cpp
I seem to recall on OS X Maverick needed to have the x86/x86_64
libraries rebuilt or configured for command line tools but I don't
remember the procedure off-hand.
Thank you for replying. You are right there are lots of commented lines. As I said to Alf, the problem was I didn't not think that we needed to link all *.cpp files. I used g++ Fig11_04.cpp -o Fig without linking the other c++ file. I should've used this g++ Fig11_04.cpp PhoneNumber.cpp -o Fig. In java you would compile all java files as javac *.java then run only the file with the main thread as java <file_name>, so I thought in c++ we only needed g++ Fig11_04.cpp -o Fig since Fig11_04.cpp is the only one with the main.
Actually, with g++ on the Mac you can compile a small project such as
yours with: g++ -m64 *.cpp just as you do with Java. The resulting
executable will be a.out and you can fix that by commanding:
g++ -m64 *.cpp -o Fig11_04

Loading...