[C con Clase] Error en compilacion: Referencia a ... sin definir

Davidson, Steven srd4121 en njit.edu
Mie Mayo 21 19:21:03 CEST 2014


Hola Facundo,

2014-05-20 15:24 GMT-04:00 Facundo Curti <facu.curti en gmail.com>:

> Por que lo que necesito hacer, es una función que reciba una cadena, y
> devuelva como resultado su CRC. No necesito definir ningún objeto.
> Quiero poder trabajar con la función CRC sin necesidad de definir
> objetos.
>
>
Podrías usar eso mismo: una función global. No hace falta crear una "clase
estática". En tu caso, sólo quieres que exista la función 'crc32()'. Para
esto, mantén esta función de enlazamiento externo y las demás entidades de
enlazamiento estático. Por ejemplo,

// crc32.h

unsigned int crc32( const char *cadena, const unsigned int iCRC=0xFFFFFFFF
);


// crc32.cpp

#include "crc32.h"

static unsigned int poly;
static unsigned char flagTab;
static int table[256];

static void iniTab();
static unsigned int reflect( unsigned int bits );
static void memset( void *ptr, const int word, const int len );

unsigned int crc32( const char *cadena, const unsigned int iCRC )
{
  ...
}


Puedes pensar que 'crc32()' es una función global pública, mientras que las
demás entidades globales: funciones y variables son privadas, desde el
punto de vista de "crc32.cpp".

Podemos extender esto un poco más y agregar un espacio con nombre. Por
ejemplo,

// crc32.h

namespace CRC32
{

unsigned int crc32( const char *cadena, const unsigned int iCRC=0xFFFFFFFF
);

}


// crc32.cpp

#include "crc32.h"

namespace CRC32
{

static unsigned int poly;
static unsigned char flagTab;
static int table[256];

inline static void iniTab();
inline static unsigned int reflect( unsigned int bits );
inline static void memset( void *ptr, const int word, const int len );

inline unsigned int crc32( const char *cadena, const unsigned int iCRC )
{
  ...
}

}

No tienes que cambiar nada en el resto del programa: en 'main()'; esto es,

int main()
{
  CRC32::crc32( "hola" );
  ...
}

> En fin, José te ha solucionado el tema de los errores; o sea, escribe,
> >
> > unsigned int CRC32::poly = 0;
> > unsigned char CRC32::flagTab = 0;
> > int CRC32::table[256] = {0};
>
> No estoy seguro de donde hacerlo. Si lo hago en el header, me indica:
>
> crc32.h:17:28: error: ISO C++ prohíbe la inicialización en la clase
> del miembro static ‘CRC32::poly’ que no es constante
>
> Al momento de compilar el crc32.cpp. Y ya lo hago en el crc32.cpp,
> donde a poly le defino 0x04C11DB7, y a table lo inicializo en 0 con
> memset.
>
>
Las definiciones o implementaciones se deberían hacer en el código fuente;
o sea, en "crc32.cpp". Esto es,

// crc32.cpp

#include"crc32.h"
#include<stdio.h>

unsigned int CRC32::poly = 0;
unsigned char CRC32::flagTab = 0;
int CRC32::table[256] = {0};
...


Recuerda que los ficheros de cabecera se suelen incluir en varios ficheros.
Si definieras las variables en el fichero de cabecera, entonces las
estarías redefiniendo en cada fichero fuente. Sin embargo, esto quebranta
la regla de una sola definición, en C++. Por lo tanto, tiene sentido
definir las variables en un solo código fuente, y simplemente incluir la
declaración en otros códigos fuente, mediante el fichero de cabecera.

 Lo que quiero, es utilizar la menor cantidad de librerias posibles. Y
> como memset está dentro de string.h, he creado un memset propio para
> no tener que incluir la libreria.
>
>
Entiendo. Otra posibilidad es comunicar al enlazador que sólo quieres
enlazar una función en una biblioteca. Esto ya es cuestión de las opciones
del enlazador.

Lo que quiero, es obtener la longitud en bits de la cadena (De nuevo,
> sin recurrir a string.h). La idea era que el sizeof me diera la
> longitud de la cadena en bytes, y multiplico por 8 para obtener la
> cantidad de bits.
>
> De todas formas es solo una prueba que estaba haciendo para ver si
> resultaba o no. Ahora que lo dices, creo que tienes razón, y me
> devolveria el tamaño del char en lugar de la cadena. Creo que
> recurriré a escribir mi propio strlen.
>
>
La otra posibilidad es que pases ese dato como parámetro. A veces es más
sencillo calcular ese valor o incluso darlo directamente desde la función
invocadora.


Hasta pronto,

Steven
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20140521/5c3d8302/attachment.html>


Más información sobre la lista de distribución Cconclase