Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Fallos a la hora de coimpilar y enlazar archivos con g++

Estas en el tema de Fallos a la hora de coimpilar y enlazar archivos con g++ en el foro de C/C++ en Foros del Web. A ver, les explico, estoy empezando a trabajar en Ubuntu y usando el compilador de g++ para intentar empezar a elaborar programas más complejos. En ...
  #1 (permalink)  
Antiguo 18/11/2012, 12:26
Avatar de RsG
RsG
 
Fecha de Ingreso: febrero-2008
Mensajes: 16
Antigüedad: 16 años, 1 mes
Puntos: 0
Fallos a la hora de coimpilar y enlazar archivos con g++

A ver, les explico, estoy empezando a trabajar en Ubuntu y usando el compilador de g++ para intentar empezar a elaborar programas más complejos.

En esta ocasión, intento trabajar los conceptos de composición y trabajo con lo siguiente:

- Una clase Punto. Donde trabajo con punto.cc y punto.h, en el primero las implementaciones y en el segundo las cabezeras y definición de la clase.

- Una clase Spair, que cuenta con sus ficheros .cc y .h al igual que la clase punto.

- Un fichero Programa.cc donde elaboraré las pruebas con las distintas funciones y constructores que quiero trastear.

El problema viene, que ahora que tengo una versión lo más sencilla posible, a la hora de compilar solo consigo generarme errores que me dicen que existen referencias sin definir.

Lo que llevo programado hasta el momento, es lo siguiente

Punto.cc

Código:
#include <punto.h>


punto::punto(const int o, const int a){
  data.SetAbscisa(a); 
  data.SetOrdenada(o);
};
Punto.h
Código:
#ifndef __EDI_PUNTO_H_
#define __EDI_PUNTO_H_

#include <iostream>
#include <spair.h>

//using namespace std;


class punto
{
  public:
    // constructores
    punto (); 		  	// punto (0,0)
    punto (int x, int y);	// punto (x,y)
 
    // asignacion
    void operator = (const punto & rhs);

    // observadores
    int abcisa () const;
    int ordenada () const;

  private:
    // area de datos
    // Un par de enteros (x:ordenada, y:abcisa)
    spair<int, int> data;

};

#endif
La clase punto, tiene que recibir por composición un área de datos basada de tipo spair<k,v>, por eso creo los dos ficheros de la clase spair.

Spair.cc

Código:
#include <spair.h>


template<class T, class U>
spair<T,U>::spair(const int o, const int a){
  abscisa = a;
  ordenada = o;
};
Spair.h

Código:
#include <iostream>

//using namespace std;
template <class T, class U>
class spair
{
 
  
  public:

  // Constructor
  spair (int x, int y);
  spair ();

  // Asignacion
  T SetAbscisa (T abs);
  U SetOrdenada(U ord);
  
  private:

  T abscisa;
  U ordenada;
};
Programa.cc

Código:
#ifndef __EDI_PUNTO_H_
#define __EDI_PUNTO_H_

#include <iostream>
#include <spair.h>
#include <punto.h>

using namespace std;

int main (){
	
	punto a;
	cout << a;
	cout << "Hola Mundo";
}

#endif
Con estos cinco ficheros, creo que el orden correcto de compilación, sería

1º Compilar la clase Spair

Código:
g++ ./Escritorio/spair.cc -I ./Escritorio
Utilizo la opción -I para seleccionar el directorio donde quiero que busque spair.h, pero esta compilación, ya empieza a fallar dándome errores de falta de referencias

Código:
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: En la función `_start':
(.text+0x20): referencia a `main' sin definir
/tmp/ccKOnjJP.o: En la función `__static_initialization_and_destruction_0(int, int)':
spair.cc:(.text+0x23): referencia a `std::ios_base::Init::Init()' sin definir
spair.cc:(.text+0x32): referencia a `std::ios_base::Init::~Init()' sin definir
collect2: error: ld devolvió el estado de salida 1
2º Compilar la clase Punto, con los mismos errores que en el punto uno pero propios de su clase.
3º Compilar el Programa, cosa aún no he podido realizar pero que se supone, que tendría que hacer en función de dos objetos que son el resultado de la compilación correcta de las dos clases anteriores.

Llevo toda la tarde haciendo todo tipo de pruebas y aún no he dado con lo que falla, probablemente sea un error estúpido y simple, pero estoy empezando a investigar en este mundillo... cualquiera que me aportase un poco de luz o me diese alguna idea, no se si meter algún typdef en punto para los valores de abscisa y ordenada, me sería de gran ayuda.

Gracias
  #2 (permalink)  
Antiguo 18/11/2012, 18:27
Avatar de cotolon  
Fecha de Ingreso: octubre-2012
Mensajes: 55
Antigüedad: 11 años, 5 meses
Puntos: 10
Respuesta: Fallos a la hora de coimpilar y enlazar archivos con g++

te faltó un return 0 dentro de la función main, lo demás no lo sé.
  #3 (permalink)  
Antiguo 19/11/2012, 02:15
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 13 años, 10 meses
Puntos: 73
Respuesta: Fallos a la hora de coimpilar y enlazar archivos con g++

Punto.h: Has puesto

#ifndef __EDI_PUNTO_H_
#define __EDI_PUNTO_H_

al principio, para evitar redefiniciones. Es correcto, pero es que luego lo vuelves a poner al principio de programa.cc, con lo que, al compilar, cuando llega a #include <punto.h>, te descarta la definición de la clase punto. Elimina esas dos líneas de programa.cc, y a ver qué errores te da ahora al compilar.

Saludos,
  #4 (permalink)  
Antiguo 20/11/2012, 03:08
Avatar de RsG
RsG
 
Fecha de Ingreso: febrero-2008
Mensajes: 16
Antigüedad: 16 años, 1 mes
Puntos: 0
Respuesta: Fallos a la hora de coimpilar y enlazar archivos con g++

Cita:
Iniciado por Fw190 Ver Mensaje
Punto.h: Has puesto

#ifndef __EDI_PUNTO_H_
#define __EDI_PUNTO_H_

al principio, para evitar redefiniciones. Es correcto, pero es que luego lo vuelves a poner al principio de programa.cc, con lo que, al compilar, cuando llega a #include <punto.h>, te descarta la definición de la clase punto. Elimina esas dos líneas de programa.cc, y a ver qué errores te da ahora al compilar.

Saludos,
Eliminando lo que me dices tu, al menos ahora me salen otros tipos de errores a la hora de compilar Programa.cc aunque es un poco locura el resultado, solo puedo copiar una pequeña parte ya que son infinidad de errores

Código:
./Escritorio/programa.cc:18:10: nota:   no se puede convertir ‘a’ (tipo ‘punto’) al tipo ‘const char*’
In file included from /usr/include/c++/4.7/iostream:40:0,
                 from ./Escritorio/programa.cc:9:
/usr/include/c++/4.7/ostream:528:5: nota: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const char*)
/usr/include/c++/4.7/ostream:528:5: nota:   falló la deducción/sustitución del argumento de plantilla:
./Escritorio/programa.cc:18:10: nota:   no se puede convertir ‘a’ (tipo ‘punto’) al tipo ‘const char*’
In file included from /usr/include/c++/4.7/iostream:40:0,
                 from ./Escritorio/programa.cc:9:
/usr/include/c++/4.7/ostream:541:5: nota: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const signed char*)
/usr/include/c++/4.7/ostream:541:5: nota:   falló la deducción/sustitución del argumento de plantilla:
./Escritorio/programa.cc:18:10: nota:   no se puede convertir ‘a’ (tipo ‘punto’) al tipo ‘const signed char*’
In file included from /usr/include/c++/4.7/iostream:40:0,
                 from ./Escritorio/programa.cc:9:
/usr/include/c++/4.7/ostream:546:5: nota: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const unsigned char*)
/usr/include/c++/4.7/ostream:546:5: nota:   falló la deducción/sustitución del argumento de plantilla:
./Escritorio/programa.cc:18:10: nota:   no se puede convertir ‘a’ (tipo ‘punto’) al tipo ‘const unsigned char*’
usuario@ubuntu:~$ clear

usuario@ubuntu:~$ g++ ./Escritorio/programa.cc -I ./Escritorio/
In file included from ./Escritorio/punto.h:2:0,
                 from ./Escritorio/programa.cc:11:
./Escritorio/spair.h:5:7: error: redefinición de ‘class spair<T, U>’
In file included from ./Escritorio/programa.cc:10:0:
./Escritorio/spair.h:5:7: error: definición previa de ‘class spair<T, U>’
./Escritorio/programa.cc: En la función ‘int main()’:
./Escritorio/programa.cc:18:10: error: no hay coincidencia para ‘operator<<’ en ‘std::cout << a’
./Escritorio/programa.cc:18:10: nota: los candidatos son:
In file included from /usr/include/c++/4.7/iostream:40:0,
                 from ./Escritorio/programa.cc:9:
/usr/include/c++/4.7/ostream:106:7: nota: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [con _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.7/ostream:106:7: nota:   no hay una conversión conocida para el argumento 1 de ‘punto’ a ‘std::basic_ostream<char>::__ostream_type& (*)(std::basic_ostream<char>::__ostream_type&) {aka std::basic_ostream<char>& (*)(std::basic_ostream<char>&)}’
/usr/include/c++/4.7/ostream:115:7: nota: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ios_type& (*)(std::basic_ostream<_CharT, _Traits>::__ios_type&)) [con _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>; std::basic_ostream<_CharT, _Traits>::__ios_type = std::basic_ios<char>]
/usr/include/c++/4.7/ostream:115:7: nota:   no hay una conversión conocida para el argumento 1 de ‘punto’ a ‘std::basic_ostream<char>::__ios_type& (*)(std::basic_ostream<char>::__ios_type&) {aka std::basic_ios<char>& (*)(std::basic_ios<char>&)}’
/usr/include/c++/4.7/ostream:125:7: nota: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [con _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.7/ostream:125:7: nota:   no hay una conversión conocida para el argumento 1 de ‘punto’ a ‘std::ios_base& (*)(std::ios_base&)’
/usr/include/c++/4.7/ostream:164:7: nota: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [con _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.7/ostream:164:7: nota:   no hay una conversión conocida para el argumento 1 de ‘punto’ a ‘long int’
/usr/include/c++/4.7/ostream:168:7: nota: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [con _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.7/ostream:168:7: nota:   no hay una conversión conocida para el argumento 1 de ‘punto’ a ‘long unsigned int’
/usr/include/c++/4.7/ostream:172:7: nota: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [con _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.7/ostream:172:7: nota:   no hay una conversión conocida para el argumento 1 de ‘punto’ a ‘bool’
In file included from /usr/include/c++/4.7/ostream:607:0,
                 from /usr/include/c++/4.7/iostream:40,
                 from ./Escritorio/programa.cc:9:
/usr/include/c++/4.7/bits/ostream.tcc:93:5: nota: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [con _CharT = char; _Traits = std::char_traits<char>]
/usr/include/c++/4.7/bits/ostream.tcc:93:5: nota:   no hay una conversión conocida para el argumento 1 de ‘punto’ a ‘short int’
In file included from /usr/include/c++/4.7/iostream:40:0,
                 from ./Escritorio/programa.cc:9:
.
.
.
.
.
.
.
.
Estoy trabajando con estos nuevos errores a ver si soy capaz de solucionarlos, el problema es que la compilación de Spair.cc también falla

Código:
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: En la función `_start':
(.text+0x20): referencia a `main' sin definir
collect2: error: ld devolvió el estado de salida 1
Y la de Punto.cc también

Código:
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: En la función `_start':
(.text+0x20): referencia a `main' sin definir
/tmp/ccxLf0AK.o: En la función `punto::punto(int, int)':
punto.cc:(.text+0x1a): referencia a `spair<int, int>::spair()' sin definir
punto.cc:(.text+0x2b): referencia a `spair<int, int>::SetAbscisa(int)' sin definir
punto.cc:(.text+0x3c): referencia a `spair<int, int>::SetOrdenada(int)' sin definir
collect2: error: ld devolvió el estado de salida 1
Siempre esas referencias que no se como quitar de ahí.

Gracias por la ayuda, soy bastante novato en esto y sigo trabajando en aprender!
  #5 (permalink)  
Antiguo 20/11/2012, 04:10
Avatar de RsG
RsG
 
Fecha de Ingreso: febrero-2008
Mensajes: 16
Antigüedad: 16 años, 1 mes
Puntos: 0
Respuesta: Fallos a la hora de coimpilar y enlazar archivos con g++

A ver, comento, creo que mi último mensaje se puede olvidar y sigo desde aquí, ya que investigando he realizado algunas modificaciones y creo que la cosa va ligeramente mejor aunque sigue fallando.

Spair.h

Al querer declarar esta clase como plantilla, he visto que tengo que meter todo en el mismo archivo de cabecera .h y me queda tal que así. En este, he echo la trampa de renombrarlo .cc y añadir al final una función main con un simple return 0 y la compilación funcionaba sin darme ningún error por lo que creo que esta, ya está funcionando correctamente y se queda tal que así.

Código:
#include <iostream>

using namespace std;

template <class T, class U>
class spair {
 
  public:

  // Constructor
  spair (T x, U y);
  spair ();

  // Observadores

  T RetAbscisa () const;
  U RetOrdenada () const;

  // Asignacion
  T SetAbscisa (T abs);
  U SetOrdenada(U ord);
  
  private:

  T abscisa;
  U ordenada;
};


template<class T, class U>
spair<T,U>::spair(const T a, const U o){
  abscisa = a;
  ordenada = o;
};

template<class T, class U>
T spair<T,U>::RetAbscisa () const {
	return abscisa;
}

template<class T, class U>
T spair<T,U>::SetAbscisa(T abs){
  abscisa = abs;
}

template<class T, class U>
U spair<T,U>::RetOrdenada () const {
	return ordenada;
}

template<class T, class U>
U spair<T,U>::SetOrdenada (U ord){
	ordenada = ord;
}
Punto.h

Código:
#include <iostream>
#include <nspair.h> // La nueva versión de Spair la he llamado nspair.h de ahí el cambio

//using namespace std;


class punto
{
  public:
    // constructores
    punto (); 		  	// punto (0,0)
    punto (const int x, const int y);	// punto (x,y)
    punto (const punto & rhs);

    // asignacion
    void operator = (const punto & rhs);

    // observadores
    int abcisa () const;
    int ordenada () const;

  private:
    // area de datos
    // Un par de enteros (x:ordenada, y:abcisa)
    spair<int, int> data;

};
Punto.cc

Aquí es donde estoy encontrandome el problema, ya que no se si estoy usando correctamente el constructor. Ya que punto, quiero que se base en la declaración de Spair e igual estoy metiendo la pata a la hora de implementarlo

Código:
#include <punto.h>


punto::punto(const int a, const int o){
  data = spair<int,int> (a,o);
};
El error que me da al compilar es el siguiente

Código:
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: En la función `_start':
(.text+0x20): referencia a `main' sin definir
/tmp/cc6F2l2c.o: En la función `punto::punto(int, int)':
punto.cc:(.text+0x1a): referencia a `spair<int, int>::spair()' sin definir
collect2: error: ld devolvió el estado de salida 1
Y luego por último, tengo Programa.cc que si lo compilo me sigue dando una lista interminable de errores aunque creo que la mayoría son porque está mal compilado punto y falla a la hora de realizar el enlazado.

Seguiré investigando sobre esta nueva versión que estoy haciendo.

Gracias, un saludo y perdón por las molestias, solo quiero aprender!
  #6 (permalink)  
Antiguo 20/11/2012, 14:43
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 13 años, 10 meses
Puntos: 73
Respuesta: Fallos a la hora de coimpilar y enlazar archivos con g++

La verdad, no estoy muy ducho en C++, yo utilizo C, pero para empezar sí que puedo decirte que lo de la referencia a 'main' se debe a que no encuentra la función 'main' (que es el punto de entrada de todo programa C/C++). Te sugiero que postees el código (preferiblemente con el highlight), así como la línea de comando con la que compilas.

Etiquetas: c++, g++, templates
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 20:43.