error de multiples definiciones en c

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

error de multiples definiciones en c

Notapor baigos » Jue Dic 09, 2010 2:25 am

Estoy programando en c unas cosas, el problema que tengo es que tengo unas cuantas constantes y funciones de uso comun en el codigo (o sea en los .c). Lo que hice fue agruparlas en un utils.h y un utils.c.
El problema se presenta cuando quiero incluir ese header en muchos archivos .c o .h, ya que al compilar el linker me tira error de multiples definitions de las variables y funciones de utils.
Me han dicho que se puede solucionar utilizando extern, pero lo que no entiendo es si debo volver a colocar la definicion de las variables o funciones en el .c o .h donde quiero hacer uso de ellas, pero con la palabra clave extern al comienzo?. Hay alguna otra solución?

Ej:

en utils.h y utils.c tengo una función que se llama powerof2(...)
int powerof2(...);



cuando hago uso de ella en, por ejemplo, el main.c, me tira error de que está definida en utils y en main. Debería usar el extern asi, dentro del main?:

extern int powerof2(...);
El sitio de videojuegos del nordeste argentino:
www.arcadenea.com.ar
baigos
 
Mensajes: 27
Registrado: Dom Oct 03, 2010 5:51 am

Re: error de multiples definiciones en c

Notapor hugoruscitti » Jue Dic 09, 2010 3:28 am

Me parece que se debe a que tendrías que usar las directivas
#define:

http://zator.com/Cpp/E4_9_10e.htm
http://www.todopic.com.ar/foros/index.php?topic=27406.0
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Re: error de multiples definiciones en c

Notapor Juanxo » Jue Dic 09, 2010 6:46 am

lo que te propone hugo es una posible solución, aunque en mi opinión los #define se deben evitar al máximo, ya que pueden resultar peligrosos.

Lo de extern te puede permitir usar variables de otras unidades de compilación. Yo creo que lo mejor es que postees el código de utils para que veamos donde puede fallar
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: error de multiples definiciones en c

Notapor baigos » Jue Dic 09, 2010 12:03 pm

ok, acá está el código:
Código: Seleccionar todo
#ifndef UTILS_H_
#define UTILS_H_

#include <stdio.h>

#define TRUE 1
#define FALSE 0

//verifica si es potencia de 2
int powerof2(int number);




#endif

Ahi agrupo constantes y funciones de uso común.

Este es mi makefile:
Código: Seleccionar todo
CC = g++
DEBUG = -g
CFLAGS = -Wall `sdl-config --cflags` -I./ -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
LIBS = `sdl-config --libs` -lm  -lSDL_image -lGL -lGLU

OBJECTS = main.o sprite.o render.o init.o  utils.o 

all: $(OBJECTS)
   $(CC) $(LFLAGS) $(OBJECTS) -o test $(LIBS)

%.o: %.c
   $(CC) $(CFLAGS) -c $< -o $@

clean:
   rm -f *.o test


y yo lo que venia haciendo es hacer un #include "utils.h" en otros headers donde necesitaba utilizar las constantes y funciones, por ejemplo el main.c

Oppss probé de nuevo despues de hacer un make clean, y ahora me tira error de redefinicion pero por otro lado:
init.o: In function `initgraphics()':
init.c:6: multiple definition of `screen'
main.c:24: first defined here

Este es mi header del init.h:
Código: Seleccionar todo
#ifndef INIT_H_
#define INIT_H_

#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#include "utils.h"

int const SCREEN_WIDTH = 640;
int const SCREEN_HEIGHT = 480;
int const SCREEN_BPP = 32;


SDL_Surface *screen;

void initgraphics();

#endif


Y el error me tira al hacer un #include "init.h" en el main.c, aaaaaaaa por que la vida tiene que ser tan complicadaaaa. Estoy mangueando demasiado...

Editado de nuevo:
Ahora lo que hice es no hacer el #include del "init.h", y utilizar extern:
Ej:(esto en el main.c)
Código: Seleccionar todo
extern SDL_Surface *screen;

extern void initgraphics();

Y compila sin errores (salvo que cuando quiero correr el ejecutable me da error de segmentacion, pero ese es otro tema).
Aunque la verdad no entiendo como con utils.h ahora no tengo problemas haciendo #include, y con init.h si.
El sitio de videojuegos del nordeste argentino:
www.arcadenea.com.ar
baigos
 
Mensajes: 27
Registrado: Dom Oct 03, 2010 5:51 am

Re: error de multiples definiciones en c

Notapor Juanxo » Vie Dic 10, 2010 12:00 am

yo es que no tengo demasiada experiencia con las variables globales, pero por lo que he investigado, lo que tendrías que hacer es esto:

Código: Seleccionar todo
//Init.h

extern SDL_Surface* screen; // declaración

// Main.cpp o donde sea
SDL_Surface* screen = Cualquier valor que quieras que tome


parece que tienes que hacerlo en dos pasos:
1- Decirle al compilador ¡ojo! esta variable es global a todos mis archivos
2- La variable global que tengo definida en mi programa, tiene como valor tal

Igual puedes probar a imprimir la dirección de las variables donde uses screen, y ver si son todas la misma. En caso de que alguna sea distinta ya sabrías que no te la está tratando como global

EDITO: lo de que no te de errores ahora en el utils.h igual se debe a que solo lo incluyes una vez, prueba a incluirlo en varios ficheros que no estén relacionados
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: error de multiples definiciones en c

Notapor baigos » Vie Dic 10, 2010 1:54 pm

Gracias che
Según esto que encontré:
http://www.velocityreviews.com/forums/t ... ables.html
La definición debería ir en el source, o sea el .c, y la declaración en el header, entonces lo que hice fué esto:

Código: Seleccionar todo
SDL_Surface *screen; //asi va en init.c, es la definición

extern SDL_Surface *screen; //asi va en el init.h, es la declaración


Y ahi ya no me tira errores al hacer un #include "init.h" en el main.c.
El sitio de videojuegos del nordeste argentino:
www.arcadenea.com.ar
baigos
 
Mensajes: 27
Registrado: Dom Oct 03, 2010 5:51 am


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado