views:

139

answers:

3

I tried a naive class taken from a book I found in the office.

This is it:

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

const double ANG_RAD = 0.017;

class Angulo {
  double valor;

public:
  void act_valor( double );
  double seno( void );
  double coseno( void );
  double tangente( void );
} grado;

void Angulo::act_valor( double a ) {
  valor = a;
}

double Angulo::seno(void)
{
  double temp;
  temp = sin( ANG_RAD * this.valor );
  return( temp );
}
double Angulo::coseno(void)
{
 double temp; 
 temp = cos(ANG_RAD * valor );
 return (temp);
}
double Angulo::tangente(void)
{
 return ANG_RAD * valor;
}

main()
{
 grado.act_valor( 60.0 );
 cout << "El seno del angulo es " 
      << grado.seno() << "\n";
 return(0);
}

I compiled and this is the error message I've got ( I understand now why people complain about C++ )

In file included from /usr/include/c++/4.2.1/backward/iostream.h:31,
                 from Angulo.cc:1:
/usr/include/c++/4.2.1/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
Undefined symbols:
  "std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from:
      _main in ccg0526i.o
      _main in ccg0526i.o
  "std::ios_base::Init::Init()", referenced from:
      __static_initialization_and_destruction_0(int, int)in ccg0526i.o
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::size() const", referenced from:
      std::__verify_grouping(char const*, unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)in ccg0526i.o
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned long) const", referenced from:
      std::__verify_grouping(char const*, unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)in ccg0526i.o
      std::__verify_grouping(char const*, unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)in ccg0526i.o
      std::__verify_grouping(char const*, unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)in ccg0526i.o
  "___gxx_personality_v0", referenced from:
      Angulo::act_valor(double)in ccg0526i.o
      Angulo::tangente()     in ccg0526i.o
      std::__verify_grouping(char const*, unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)in ccg0526i.o
      ___tcf_0 in ccg0526i.o
      Angulo::cosen()     in ccg0526i.o
      Angulo::seno()     in ccg0526i.o
      _main in ccg0526i.o
      unsigned long const& std::min<unsigned long>(unsigned long const&, unsigned long const&)in ccg0526i.o
      __static_initialization_and_destruction_0(int, int)in ccg0526i.o
      global constructors keyed to gradoin ccg0526i.o
      CIE in ccg0526i.o
  "std::ios_base::Init::~Init()", referenced from:
      ___tcf_0 in ccg0526i.o
  "std::basic_ostream<char, std::char_traits<char> >::operator<<(double)", referenced from:
      _main in ccg0526i.o
  "std::cout", referenced from:
      _main in ccg0526i.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Could somebody tell me what's going on?

My compiler:

Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5664~38/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5664)

I double and triple check the source in this old book and it is the same.

Thanks.

+4  A: 

Your book is outdated. The compiler you are using is much more modern, so it is simply refusing to translate the old non-standard code. It is quite possible that you can whip it into working somehow, but it would make more sense to update the code to make it standard C++. In general the code looks OK, only a few changes are necessary.

The header that you are supposed to use is <iostream>, not <iostream.h>. The compiler told you about it already. Also, the components of standard library are now in namespace std, so the output line in main should look as follows

std::cout << "El seno del angulo es " << grado.seno() << "\n";

main function must declare explicit return type

int main()
{

C++ language does not imply int by default as C did.

As additional, less important remarks, there's no need to declare parameter-less functions as (void) in C++. A mere () has exactly the same effect. Although if you like (void) better, it will work as well. Also, there's no need to take the argument of return in (). You can just say return 0;. It is also strange to see the inconsistent returns - some with () and some without (). Was it that way in the book?

AndreyT
`(void)` is more consistent with C, which is nice.
mathepic
@mathepic: I would understand the value of such consistency in bi-lingual C/C++ code, but in the above example I just don't see the point.
AndreyT
The compiler is not refusing to do anything. It merely warns you about this, if you read the first line thoroughly. It's the linker that's making trouble (perhaps for the best).
wilhelmtell
+1 for the explanation. It almost compiled, just after I read Vadim Shender answer I knew we needed `g++` BTW The book I found is this 1994 Borland C++ 4.0 :) :)
OscarRyz
@wilhelmtell for the user it doesn't make a difference. He invoked the compiler, which in turn invoked the linker. If this machinery rejects the code, it's the compiler which rejects it, from the point of the user.
Johannes Schaub - litb
@wilhelmtell: It is a matter of terminology. Formally, there's no "linker", there's only compiler, and phases of translation it goes through. If in your implementation the compiler is subdivided into smaller modules, one of which happens to be called "linker", it is merely a detail of your implementation.
AndreyT
@litb @AndreyT I didn't start this terminology war. But while we're at it, there's no "compiler": there's "computer". The computer rejects your input, and everything else is implementation detail.
wilhelmtell
@wilhelmtell: I was just explaining my use of the term *compiler* in this context, not trying to start any terminology war. I haven't just randomly invented it out of the blue. The idea was to use the *standard* terminology. While the language standard usually calls it *implementation* (or occasionaly *compiler implementation*, i.e. the term *compiler* is virtually unused) the point is that the translation process is described in terms of *phases*. There's no formal mention of any *linkers* or *computers* in the language standard.
AndreyT
+1  A: 

Fixed source:

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

const double ANG_RAD = 0.017;

class Angulo {
  double valor;

public:
  void act_valor( double );
  double seno( void );
  double coseno( void );
  double tangente( void );
} grado;

void Angulo::act_valor( double a ) {
  valor = a;
}

double Angulo::seno(void)
{
  double temp;
  temp = sin( ANG_RAD * valor );
  return( temp );
}
double Angulo::coseno(void)
{
  double temp;
  temp = cos(ANG_RAD * valor );
  return (temp);
}
double Angulo::tangente(void)
{
  return ANG_RAD * valor;
}

main()
{
  grado.act_valor( 60.0 );
  std::cout << "El seno del angulo es "
            << grado.seno() << "\n";
  return(0);
}

Compiling: g++ prog.cc -o prog

Vadim Shender
It worked, thanks, I just needed a bit of explanation of why, which I had from AndreyT
OscarRyz
Instead of math.h, please use <cmath>, main return should return an int (declaration). Better to have a default constructor for Angula.
Chubsdad
+1  A: 

Well that code definitely has some problems. First, it's including <iostream.h> but these days it should be <iostream> (unless your compiler is as old as the book.)

Secondly the grado object is a static for no good reason which is only going to confuse everybody.

And third, the code for tangente() just returns the angle in radians, not the tangent.

What are you trying to learn to do? I have a feeling that book isn't going to take you where you need to be.

Kate Gregory
+1 for the `<iostream.h>` hint
OscarRyz