Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Const O No Const

Iniciado por Pogacha, 14 de Agosto de 2004, 05:39:36 PM

« anterior - próximo »

Pogacha

 Prologo
Que tal, hace dias que no duermo, me tiemplan los parpados, se me entrecorta la respiración ...
Considero la cosa mas desanimadora del mundo, que al hacer un programa, luego de cierta elaboración, uno implemente la sencilla función para lo que todo el sistema fue diseñado; y esta malagradecida no funcione, siendo muy sencilla simplemente no funcione, uno sigue todos los pasos, controlando todo y todo este bien, parte por parte, funcion por funcion, controlando cada funcion por separado, uniendo cada parte con cada parte, pero al ejecutar el todo simplemente no funcione. No queda otra. hay un bug!!!, y de los malos!!!, van dos semanas que tengo el proyecto detenido.

Al grano:
Si hago en Visual C++ 6.0:

struct Vector
{
 void Normalizar()  { float l=longitud(); if(l>EPSILON) { l=1.0/l; x*=l; y*=l; z*=l;};
 void Sumar(const Vector &v)  { x+=v.x;  y+=v.y; z+=v.z };
 void Inverso(Vector &v)  const { v.x=-x; v.y=-y; v.z=-z};

 Vector &operator =(const Vector v) { x=v.x; y=v.y; z=v.z; return *this; }

 const float &operator[](const int i) { return ((float*)this[i]) }

 float longitud() const { return ((float)sqrt (x*x+y*y+z*z)) };

 float x,y,z;
};


Corrijanme si me equivoco:
Mi amigo const significa que permanecera constante.

Entonces en normalizar nada es const
En sumar el vector argumento es const pero this no
En inverso v no es const pero si this
En longitud this es const

En operator= el return value no es const ya que es una referencia a this.

En operator[] no se modifica nada, pero no se si eso anda bien;

el const antes de las llaves indica que el this permanecera constante (que no va a ser modificado por el codigo ahí encerrado), verdad?

Alguien sabe de consideraciones con el const cuando comienzas a usar interrelaciones de clases o trabajos con punteros o alguna otra consideracion que halla que tener en cuenta?.

Revise todo el codigo, y le desconfio a esta parte (solo intuitivamente), (en realidad es mucho mas compleja, pero en el ejemplo solo pongo lo basico). Quiero asegurarme de que esto sea así, en tal caso tendré que regresar al C (Freud diría: "es una Regresion", lo cual seria apropiado)

No descarto un bug del VC, pero seria inapropiado decir que una empresa como microsoft puede largar al mercado algo que no ande bien; fuera de broma, prefiero descartar todas las alternativas que impliquen que yo cometí el error antes de derivar la culpa a otro (aun que suene mas facil).

Saludos
Pogacha

Lord Trancos 2

 Yo de VC ni papa. Pero si te puedo decir que en Delphi, puedes tener una funcion a la que le pasas un puntero como const y modificar sin problemas la zona de memoria a la que apunta ese puntero.

No se si andaran por ahi los tiros de lo que te pasa.  :rolleyes:  
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

Pogacha

 Supuestamente si haces

char * const datos[] = "Mi nombre es pogacha";

tienes un puntero constante a datos variables

const char * datos[] = "Mi nombre es pogacha";

tienes un puntero variable a datos constantes

const char * const datos[] = "Mi nombre es pogacha";

tienes un puntero constante a datos constantes

Eso esta claro. Lo que no me queda claro son las referencias & (lamentablemente creo que son puramente del c++) con const, las funciones const y demas


gdl

 Hola hola,

Todo lo que dices, Pogacha, es cierto y, por lo que yo sé, no hay nada mal. (ole)

De todas las formas, usar const no te protege nada a la hora de ejecución, sólo de compilación. Eso sí, que si no te dió un error de compilación, lo mismo luego salta uno de ejecución por haber pinchado en una dirección incorrecta. (grrr)

Podría ser.

Aparte de una llave mal cerrada en Normalizar() que supongo que es por copiar el código al foro, lo único que modificaría sería


const float &operator[](const int i) { return ((float*)this[i]) }


por


const float &operator[](int i)const { return (&x)[i]; }
float &operator[](int i){ return (&x)[i]; }



El "const int i" no sirve para na' porque los enteros se pasan por valor y lo único que forzaría en este contexto es a que no pudieras modificar el valor de i dentro de la función (cosa que no se hace y a veces, en algunas funciones, hasta conviene poder cambiarlo).

Sobre usar dos métodos, es para mantener la constancia. Comprenderás que si el this es const, cualquier atributo suyo también será const. De la misma manera, si el this no es const, sus atributos no tienen porqué ser const. Como tú lo tenías hecho estaba bien, pero ganabas un const sin tener por qué.

Considero **muy arriesgado** usar (float*)this, sobre todo si por arte del Diablo (el de verdad, no Bill Gates), se te ocurre meter luego un método virtual o usas información de tipos en ejecución (RTTI). En este caso puede que el atributo x no esté en this, si no en this+4 o this+8 (contando en bytes). Prueba mejor poner (&x), además, te ahorras un cast.

Sobre el mensaje de "Mi nombre es pogacha", creo que sobra el [] en los ejemplos (y ya que estamos criticones, imagino que preferirás poner Pogacha en mayúscula :lol:).

Bueno, ya no se me ocurre mas na' de na', y seguro que lo que te he contado no tiene que ver con el bug ese.

Pogacha

 Si, tus comentarios me bienen re-bien
Pero voy a tratar de aclarar mi intriga del bug:

Suponete:

void funcion(const int &i)
{
 i++;  //imagina que por alguna razon el compilador no se hubiese dado cuenta de esto

}



for(i=0; i<10; i++)
{
  funcion(i);
}

Pogacha

 Ignoren el mensaje anterior, si presionas tab-espacio te lo responde por la mitad.

Si, tus comentarios me bienen re-bien
Si, la } se me escapo.

Pero voy a tratar de aclararte mi intriga:

Suponete:

void funcion(const int &i)
{
 i++;  //imagina que por alguna razon el compilador no se hubiese dado cuenta de esto
         // obviamente por algun error mio, pero dificil de encontrar.
}


for(i=0; i<10; i++)
{
  funcion(i);
  cout << i;
}

La salida seria:

1
3
5
7
9
11

Y yo muy chocho que protegí con const.
El compilador hizo algo asi:

mov eax,0
; for(i=0; i<10; i++) {
loop:
;   funcion(i);
inc eax
;   cout << i;
call cout_int // el compilador penso eax esta intacta por ende llamo a la funcion de parametro eax
int eax
cmp eac,10
jne loop;
; }

A eso le tengo miedo, y son muchas lineas para revisar, son toda la libreria matematica y geometrica.

Sobre el codigo, esta escrito en puro c/c++ pero sin nada raro, VC++ 6.0.
Los innerloops son practicamente c, para optimización y detección de errores; de igual manera se me ha escapado algo.

ethernet

 Hay una cosa que se llama sintesis y que se deberia usar el algunos mensajes para poder enterder minimamente lo que el tio que pregunta quiere.  LLevo usando conts con vc++6.0  sp5 ya tiempo y nunca he tenid ningun problema :/

Pogacha

 Cuando tienes un bug, desconfias de todo, y el problema parecia estar por ahí.
Ayer lo resolvi al fin:
Tenia un plano.h, y una vieja version en "recursos\plano.h" que diferia en la ecuacion del plano, el directorio "recursos" estaba definido en el proyecto, y al incluir "plano.h" desde otro archivo que se encontrara dentro de recursos, incluia la "recursos\plano.h", al incluir "log.h" se sorteaba el problema.

DraKKaR

 Es curioso que cuando pasan problemas de estos tan raros, el que descubre la solución es siempre el que pedía ayuda.

gdl

 
Cita de: "DraKKaR"Es curioso que cuando pasan problemas de estos tan raros, el que descubre la solución es siempre el que pedía ayuda.
Lógico, es él quién tiene toda la información. Los demás sólo podemos intuir y ayudar como buenamente se pueda.

Pogacha

 Gracias a todos, pero no esperaba que solucionaran mi problema, tan solo que me confirmaban el uso del const en VC, ya que segun el problema parecía (te juro!), que se encontraba ahí.
Luego escribo la solución por si a alguno le sirve como experiencia.
Y aun que el problema parecia sencillo, era dificil de ver, por que cambiando la ecuacion del plano
(ax+by+cz+dw=0 por ax+by+cz=dw) tambien funcionaban muchas otras partes, lo cual hacía inperceptible la diferencia.

Saludos.
Pogacha






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.