Error de compilacion C2440

Iniciado por ipadilla, 7 Julio 2010, 18:01 PM

0 Miembros y 1 Visitante están viendo este tema.

ipadilla

Estoy intentando compilar con Visual Studio 2003 un programa que fue creado con Visual Studio 6.0 y obtengo en siguiente error:

c:\En Curso_1\Chromatic\Svn\Truck\Src\Classes\CList.h(13 5) : error C2440: '=' : no se puede realizar la conversión de 'const char *' a 'char *'
Se pierden calificadores en la conversión
c:\En Curso_1\Chromatic\Svn\Truck\Src\Classes\CList.h(10 5) : vea la referencia a la creación de instancias de plantilla de función 'CList<T>::CList_Entry *CList<T>::Set<const char>(CList<T>::CList_Entry *,const char)' que se está compilando
with
[
T=char *
]
c:\En Curso_1\Chromatic\Svn\Truck\Src\Dlg_UserMenusEd.cp p(758) : vea la referencia a la creación de instancias de plantilla de función 'CList<T>::CList_Entry *CList<T>::Add<const char*>(const char)' que se está compilando
with
[
T=char *
]


¿Alguien me puede ayudar a solucionarlo?

Muchas gracias
ipadilla

EvilGoblin

Podrias poner ese fragmento de codigo en donde te marca el error??

si es

T=char *

podrias hacer

T=const char *

y si es algo  como

funcion1 = funcion2

podrias
funcion1 = (const char) funcion2


basicamente te esta diciendo que estas queriendo cargar un char * en un const char *

asi que solo necesitas igual eso
Experimental Serial Lain [Linux User]

do-while

#2
¡Buenas!
Citarno se puede realizar la conversión de 'const char *' a 'char *'
Creo que lo has entendido al reves EvilGobilin.

De echo estoy leyendo ahora un librillo en el que hablan de estos errores que nos resultan extraños. Es por la especificacion del estandar. No me la he leido (la especificacion del estandar), pero por lo que cuentan en el libro, los dos punteros son de tipo char, por lo que en principio son compatibles, pero la parte derecha de la igualdad tiene mas calificadores (apellidos del estilo const, register, static, volatile...) y al parecer copiar algo que tiene apellidos en algo que no los tiene debe de ser ilegal, por lo menos en cuanto a const y punteros se refiere.

Hum... de todas formas esto de lo que hablo es C, no se si en C++ se aplican las mismas reglas, y no se si ha quedado claro porque yo mismo no se si lo tengo muy claro. Son cosas de estas que tienes que leer una cuantas veces para poder entender como funcionan. Si alguien sabe explicar cual es el problema con las asignaciones y los calificadores quedara mejor explicado que con lo que he dicho.

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

MIG80

#3
Si declaramos:


const char *p;
char *q;
...


y luego hacemos la siguiente asignación:


q=p;


En C  nos dara un Warning; en C++ un error

En ambos casos compilara bien con un cast:


q=(char *)p;


Littlehorse

El warning se da porque al tener un modificador "const", lo que estas diciendo es algo como: Lo que tengo aquí, lo podes mirar, pero no alterar (Cambiar de valor, o mover en memoria o..dependiendo de donde este el modificador)

Al asignarlo a un puntero a char, esa protección se pierde, por lo tanto podrías afectar datos que en un principio posiblemente se hayan puesto para ser inmodificables. La idea es que en vez que el programa pueda tener un error en tiempo de ejecución, este se detecte antes, en tiempo de compilación (Ya sea por un warning en el caso de C, o un error en el caso de C++).

Hacer un cast, no es precisamente una solución, mas bien es esconder el error. En casos como ese, lo ideal es revisar que es lo que realmente se esta haciendo y lo que se quiere hacer.
En el caso de C++, si realmente se esta seguro que no se va a modificar lo que sea que este como const, se pueden utilizar los casteos seguros.

Saludos!
An expert is a man who has made all the mistakes which can be made, in a very narrow field.

ipadilla

#5
Muchas gracias a todos por vuestra ayuda. Aquí tenéis el dódigo donde se produce el error, así os será más fácil ayudarme:

// -----------------------------------------------------------------------
// CList.h: interface for the CList class
// -----------------------------------------------------------------------

#ifndef _CLIST_H_
#define _CLIST_H_

// -----------------------------------------------------------------------
// Includes
#include <stdlib.h>
#include <string.h>

// -----------------------------------------------------------------------
// Class definition
template <typename T> class CList
{
   public:

       #define ERASE_CALLBACK void (*CallBack)(T Content)

       struct CList_Entry
       {
           struct CList_Entry *Next;
           struct CList_Entry *Previous;
           T Content;
       };

       // Default Constructor/Destructor
       CList()
       {
           Free_Content = 0;
           Nbr_Entries = 0;
           Last_Entry = 0;
           First_Entry = 0;
       }

       ~CList()
       {
           this->Erase();
       }

       void Erase(ERASE_CALLBACK = NULL)
       {
           CList_Entry *Entry_To_Free;

           // Take first entry in the list
           Entry_To_Free = this->First_Entry;

           while(Entry_To_Free)
           {
               First_Entry = Entry_To_Free->Next;
               if(CallBack)
               {
                   CallBack(Entry_To_Free->Content);
               }
               Del(Entry_To_Free);
               Entry_To_Free = First_Entry;
           }
       }

       int Amount(void)
       {
           return(Nbr_Entries);
       }

       CList_Entry *Add(T Datas, int Size)
       {
           CList_Entry *New_Entry = Create_Entry(Size);
           Set(New_Entry, Datas, Size);
           return(New_Entry);
       }

       template<typename T> CList_Entry *Add(T Datas)
       {
           CList_Entry *New_Entry = Create_Entry(0);
           Set(New_Entry, Datas);
           return(New_Entry);
       }

       template< > CList_Entry *Add<char *>(char *Datas)
       {
           int Size = strlen(Datas) + 1;
           CList_Entry *New_Entry = Create_Entry(Size);
           Set(New_Entry, Datas, Size);
           return(New_Entry);
       }

       void MAdd(int Number, T Datas)
       {
           while(Number)
           {
               Add(Datas);
               Number--;
           }
       }

       CList_Entry *Set(int Entry_Number, T Datas)
       {
           CList_Entry *Entry_To_Set = Get(Entry_Number);
           Set(Entry_To_Set, Datas);
           return(Entry_To_Set);
       }

       template<typename T> CList_Entry *Set(CList_Entry *Entry_To_Set, T Datas)
       {
           Entry_To_Set->Content = (T) Datas;  -----Esta es la línea del error
           return(Entry_To_Set);
       }

       template< > CList_Entry *Set<char *>(CList_Entry *Entry_To_Set, char *Datas)
       {
           return(Set(Entry_To_Set, Datas, strlen(Datas) + 1));
       }

       CList_Entry *Set(int Entry_Number, T Datas, int Size)
       {
           CList_Entry *Entry_To_Set = Get(Entry_Number);
           Set(Entry_To_Set, Datas, Size);
           return(Entry_To_Set);
       }

       CList_Entry *Set(CList_Entry *Entry_To_Set, T Datas, int Size)
       {
           free((void *) Entry_To_Set->Content);
           Entry_To_Set->Content = (T) calloc(Size, 1);
           memcpy((void *) Entry_To_Set->Content, (void *) Datas, Size);
           Free_Content = 1;
           return(Entry_To_Set);
       }

       CList_Entry *Get(CList_Entry *Entry_To_Get)
       {
           CList_Entry *Current_Entry;

           Current_Entry = this->First_Entry;
           while(Current_Entry != Entry_To_Get)
           {
               Current_Entry = Current_Entry->Next;
           }
           return(Current_Entry);
       }

       CList_Entry *Get(int Entry_Number)
       {
           CList_Entry *Entry_To_Get;

           Entry_To_Get = First_Entry;
           while(Entry_Number)
           {
               Entry_To_Get = Entry_To_Get->Next;
               Entry_Number--;
           }
           return(Entry_To_Get);
       }

       void Del(CList_Entry *Entry_To_Delete)
       {
           CList_Entry *Previous_Entry;
           CList_Entry *Next_Entry;

           if(!First_Entry)
           {
               Nbr_Entries = 0;
               Last_Entry = 0;
               First_Entry = 0;
               return;
           }
           // First will be next
           if(First_Entry == Entry_To_Delete) First_Entry = Entry_To_Delete->Next;
           // Last will be previous
           if(Last_Entry == Entry_To_Delete) Last_Entry = Entry_To_Delete->Previous;
           // Get next/previous entries
           Previous_Entry = Entry_To_Delete->Previous;
           Next_Entry = Entry_To_Delete->Next;
           if(Free_Content)
           {
               free((void *) Entry_To_Delete->Content);
           }
           free(Entry_To_Delete);
           // Update previous/next entries
           if(Next_Entry) Next_Entry->Previous = Previous_Entry;
           if(Previous_Entry) Previous_Entry->Next = Next_Entry;
           if(this->Nbr_Entries) this->Nbr_Entries--;
       }
};

#endif

Gracias de nuevo a todos, ahora comprobaré vuestas aportaciones. La línea que produce el error tiene una nota en rojo
ipadilla


Lh: No hagas doble post, usa el botón modificar.

Hola a todos,
pues no logro eliminar el error, me podéis porner un ejemplo ahora que teneis el código.
Muchas gracias
ipadilla

Hola Littlehorse,
Alleluya!!!,  he encontrado el botón modificar, perdón por mi torpeza.
He probado las propuestas que me han hecho en este foro, pero no he logrado que me funcione. Posiblemente no lo hago bien. ¿Me podrías explecar cono realizar un casteo seguro, ahora que dispones del código?. Si necesitas algo más me lo puedes pedir.
gracias y saludos
iapdilla