Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Menu

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menu

Mensajes - davur

#1
General Programadores / Re: Programar para iPhone
20 de Agosto de 2009, 07:27:08 PM
Cita de: Prompt en 17 de Agosto de 2009, 04:19:50 PM
La mayoria de los problemas que provocan usar estas porquerias de mierda asquerosas y putrefactas de lenguajes de programación son el control de memoria, los buffer overrun y overflow. Utilizar ObjC le asegura a apple que la gente no hará que su device pete cada 2 x 3. Pero es que nadie quiere la porqueria del ObjC, que yo sepa todo el mundo lo odia. Es cierto?

No, todo lo que dices en el párrafo citado es rotundamente falso. No tienes ni idea de lo que hablas.

Cita de: Prompt en 20 de Agosto de 2009, 07:39:05 AM
Si, lo se. Yo me refiero a 2 problemas comunes en tiempos de ejecución por lo que existe C# por ejemplo. Windows tiene un problema que los programadores, programan mal y rápido porque hay mucho jefe inutil o gente que no entiende bien la industria, bien no entremos ahí.

...

Son muchas barbaridades juntas: eres el perfecto ejemplo de 'language zealot'. La contestación de Vicente es ejemplar, y correctísima.

Lenguajes modernos y mejor diseñados que C++, como C# o Python, tienen características en absoluto triviales de dominar. Bien harías en informarte antes de decir barbaridades como que su premisa básica es que "el programador es tonto". Porque lo único que haces es dar a entender que eres el tonto aquí.
#2
Principiantes / Re: plantilla posiciones
20 de Agosto de 2009, 06:31:57 PM
No es buen estilo utilizar el preprocesador con este propósito. Utiliza constantes reales. Y, si realmente quieres tenerlas unificadas en una clase (que puede ser discutible), entonces puedes hacer:

struct Refs
{
    static const int SCR_W = 240;
    static const int SCR_H = 320;

    static const int TITLE_POS_Y = 10;
    static const int MENU_POS_Y = 50;

    // ...
};


Nótese que puedes inicializar los miembros estáticos en la propia declaración de clase únicamente porque son constantes y de tipo integral. Si no fuera así, tendrías que definirlos fuera de la declaración de clase.
#3
General Programadores / Re: Duda de novato en c (creo)
14 de Junio de 2009, 09:28:20 PM
Los problemas que pueden causar las variables globales se solucionan no utilizando variables globales en primer lugar.
#4
Principiantes / Re: como verificar objetos null en c++
07 de Junio de 2009, 11:36:14 PM
HarvesterOfAcorns, ten en cuenta que Pogacha está comprobando que p no es nulo (es decir, que apunta a un objeto de tipo int) antes de dereferenciarlo, precisamente para evitar el comportamiento indefinido que comentábamos antes.
#5
Principiantes / Re: como verificar objetos null en c++
07 de Junio de 2009, 11:28:21 PM
Cita de: Ruben en 07 de Junio de 2009, 10:05:47 PM
La segunda, creo que no nos saca de pobres. Vamos, que nadie le impide al tio que este usando la interfaz coger el puntero a pelo del smart pointer y hacer un delete, delete[] o format c:... :P . Si la quiere liar, lo va hacer igual uses smart pointers o documentandolo.

Bueno, no me refería a protegerse de Maquiavelo, sino a protegerse de errores no intencionados (que son los que interesa evitar). Para hacer lo que comentas con un puntero inteligente es necesaria una subversión explícita de su forma de uso.
#6
Principiantes / Re: como verificar objetos null en c++
07 de Junio de 2009, 09:18:51 PM
Cita de: Ruben en 07 de Junio de 2009, 08:15:43 PM
CitarSi estás utilizando punteros llanos en gran parte de tu código, posiblemente estás haciendo las cosas mal.
Aunque se va un poco del tema del post, molaria saber el por qué de esa afirmacion. :) Gracias.

Principalmente, por dos motivos:

- RAII, exception-safety, seguridad, claridad y mantenibilidad. Si comparamos este fragmento de código:


Foo* p = new Foo;

try
{
    p->do_something();
}
catch (...)
{
    delete p;
    throw;
}

delete p;


con este otro:


boost::scoped_ptr<Foo> p(new Foo);
p->do_something();


, vemos que en el segundo obtenemos automáticamente dos cosas: el código es más claro y más seguro ante la presencia de excepciones (no dejamos en manos del programador la responsabilidad de liberar la memoria en ningún caso, ni el normal ni el excepcional). De nuevo, estoy suponiendo un uso moderno del lenguaje al dar por sentada la posible aparición de excepciones en la ejecución del programa.

- Semántica de propiedad de los recursos (memoria u otros) más clara. Consideremos:


Foo* create_a_foo();


y:


boost::shared_ptr<Foo> create_a_foo();


En el primer código, es posible cometer varios errores:

- Olvidarse de hacer el delete o delete[] del puntero recibido => memory leak.
- Confundir delete con delete[].
- Hacer un doble delete del puntero recibido.

Sí, son fallos humanos que no deberían ocurrir. Pero ocurren. Y el segundo código los imposibilita todos automáticamente.

Y además, marca de manera explícita en el código quién es/son el/los propietario/s de la memoria u otros recursos (esto es especialmente útil para reforzar los contratos de las interficies que creamos o utilizamos, especialmente en lo referente a parámetros y valores de retorno de funciones).

Y de ahí mi afirmación anterior. Pero nótese que me he cuidado muy mucho de no adoptar una postura "todo o nada": definitivamente, en ocasiones es necesario utilizar punteros llanos (por ejemplo, por motivos de eficiencia por frame, es habitual que la implementación de un sistema de partículas o de una malla de geometría utilice punteros llanos). Pero para gestionar la lógica general de una aplicación, ese famoso 80% en el que no es ventajoso optimizar más allá de cierto umbral, es idiomático (es decir, buen estilo) y prácticamente obligado el uso de herramientas de más alto nivel, por todos los motivos anteriores.
#7
Principiantes / Re: como verificar objetos null en c++
07 de Junio de 2009, 07:57:47 PM
Sí, se llama al constructor por defecto implícitamente (y si este no existiera, el compilador emitiría un error), precisamente porque el objeto reside en el stack. Otro ejemplo en el que esto se ve más claramente consiste en utilizar un constructor con argumentos:


AUX_RGBImageRec textureImage("image.tex");
#8
Principiantes / Re: como verificar objetos null en c++
07 de Junio de 2009, 07:02:06 PM
Si tienes:


AUX_RGBImageRec textureImage;


Entonces el objeto textureImage está correctamente inicializado (en la zona de memoria conocida como stack, que no debes preocuparte de liberar manualmente), asumiendo que la clase AUX_RGBImageRec tiene un constructor por defecto que se encarga de la correcta inicialización, que debería ser el caso porque los constructores en C++ se utilizan para asegurar las invariantes de una clase (lanzando una excepción en caso de no poder hacerlo).

Por otro lado, si tienes:


AUX_RGBImageRec* textureImage;


Entonces textureImage no está inicializado, y apunta a una dirección de memoria indefinida. Mientras que si tienes:


AUX_RGBImageRec* textureImage = 0;


Sabes que textureImage está inicializado con el valor del puntero nulo (pero no apunta a ningún objeto de tipo AUX_RGBImageRec válido), y puedes utilizar ese hecho para que el objeto participe en contextos booleanos.

Y si tienes:


AUX_RGBImageRec* textureImage = new AUX_RGBImageRec(...);
//...
delete textureImage;


Entonces la situación es básicamente la misma que en el primer caso: asumiendo que el constructor de textureImage no ha lanzado ninguna excepción, textureImage apunta a una región de memoria que contiene un objeto AUX_RGBImageRec correctamente inicializado (pero en esta ocasión en la zona de memoria conocida como free store; deberás liberar dicha región posteriormente y de manera manual con delete).

Tanto para evitar memory leaks ante la presencia de excepciones como para evitar tener que liberar la memoria manualmente, utiliza algún tipo de puntero inteligente, como std::auto_ptr. Es la manera estándar de proceder en C++.
#9
Principiantes / Re: Problemas con el preprocesador
07 de Junio de 2009, 10:26:10 AM
Mal asunto si estás almacenando las variables de la lógica de tu juego de manera global.

Con respecto a #ifndef _MAIN_GLOBAL, ten en cuenta que utilizar nombres que comiencen por underscore seguido de mayúscula es comportamiento indefinido según el estándar (17.4.3.1.2/1):

Cita de: El estándar de C++
Certain sets of names and function signatures are always reserved to the implementation:

— Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.

- Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

Es decir, ¡no lo hagas!
#10
Principiantes / Re: como verificar objetos null en c++
07 de Junio de 2009, 10:15:36 AM
Varias cosas.

- NULL sí forma parte del estándar de C++ (¿cómo si no aseguras la compatibilidad con C?), concretamente su definición aparece en el apartado C.2.2.3/1:

Cita de: El estándar de C++
The macro NULL, defined in any of<clocale>, <cstddef>, <cstdio>, <cstdlib>, <cstring>, <ctime>, or <cwchar>, is an implementation-defined C++ null pointer constant in this International Standard (18.1).

- Una definición válida, pero enormemente limitada y que no abarca todas sus sutilezas, es que un puntero es una dirección de memoria. Y no, un puntero no es un número: a diferencia de los números, los punteros sólo pueden compararse por orden en casos muy específicos, no pueden convertirse a y desde números de manera fiable generalmente, y no obedecen correctamente a la aritmética de números.

- Siendo p un puntero no inicializado, el comportamiento de *p es indefinido. Si tienes suerte, se manifestará en un crash en tiempo de ejecución. Pero no tienes ninguna garantía de ello, precisamente porque el comportamiento es indefinido.

- El puntero nulo evalúa a false en un contexto booleano, mientras que todos los demás punteros evalúan a true.

- La constante entera 0 evalúa al puntero nulo en un contexto de punteros.

- C++ idiomático y moderno restringe enormemente el uso de punteros, y en su lugar opta por abstracciones de más alto nivel como std::auto_ptr o std::tr1::shared_ptr (entre otros). Si estás utilizando punteros llanos en gran parte de tu código, posiblemente estás haciendo las cosas mal.

- El código de la clase AUX_RGBImageRec es horrible, y ya en pocas líneas muestra muchas formas de cómo no hacer las cosas en C++. Comenzando por el uso de memset para inicializar un puntero a 0 y terminando en el uso de free en lugar de delete.
#11
Proyectos / Re: Programadores e infografistas para proyecto
01 de Junio de 2009, 09:37:46 PM
Es lo que tienen los trolls. Don't feed the trolls!
#12
Varios pequeños apuntes.

Cita de: Mars Attacks en 28 de Mayo de 2009, 02:18:27 PM
Unos años después empecé a trabajar en videojuegos con un lenguaje propio de la empresa, similar a C++. Ya se me había olvidado cómo iba lo de la herencia y la virtualización, pero la migración fue fácil.

'Virtualización' es un concepto que no tiene nada que ver con C++.

Cita de: Mars Attacks en 28 de Mayo de 2009, 02:18:27 PM
Y al final, desarrollando para Wii, aprendí C++ más en serio (lo suficiente como para saber que hay verdaderos ninjas sueltos por ahí y que está todo por aprender). Por cierto, afortunadamente Codewarrior no es el compilador (menudo infierno de programa inestable); usando makefiles puedes compilar perfectamente  'a la gcc' con el compilador que trae el SDK de la Wii, y que es al que invoca tanto ahora Codewarrior como antes hacía Radix. De hecho, los conocimientos que adquirí para gcc o g++ en casa o en la carrera me sirvieron por completo para generar el makefile para Wii.

El compilador que trae el SDK de la Wii es el que proporciona Freescale y que se incluye en su conjunto de desarrollo conocido como CodeWarrior, y que, por poder, puedes llamar 'pepito' si quieres (el resto de desarrolladores posiblemente sigamos llamándole CodeWarrior porque, bueno, es así como se llama oficialmente). Pero no es g++ (desafortunadamente para los que trabajamos/hemos trabajado con CodeWarrior).

Sí que es totalmente cierto que en la práctica se suelen utilizar makefiles a pelo para, entre otras cosas, poder utilizar Visual Studio como IDE. Lo cual no tiene nada que ver con el hecho de que tener experiencia con g++, desgraciadamente, poca aplicación directa va a tener en CodeWarrior, por ejemplo (e insisto, desafortunadamente).

Cita de: Mars Attacks en 28 de Mayo de 2009, 02:18:27 PM
-No hay motivos para descartar un lenguaje en concreto, mientras te sirva para aprender genéricamente el funcionamiento de un programa. Es más importante tener conocimientos profundos de algorítmica; todo lo demás son traducciones. Así que de todos puedes aprender algo, y nada te impide empezar por algo básico que entiendas bien y subir peldaños. Aunque te pueda parecer una pérdida de tiempo, probablemente adelantarás más si empiezas por una base firmemente asentada de los aspectos principales.

Sí los hay, por supuesto. El hecho de que ciertos lenguajes (como C++) oscurezcan el entendimiento de los fundamentos, el más importante de ellos y el que se ha recalcado ya varias veces.

Cita de: Mars Attacks en 28 de Mayo de 2009, 02:18:27 PM
-Puedes usar gcc o g++, seguramente antes o después te cruzarás con ellos o con similares.

Si cuando te encuentres con esos otros compiladores asumes que van a generar código como lo hace g++, y más tarde descubras que no es así, tendrás que olvidarte de esas asunciones para el nuevo compilador y aprender los detalles específicos a este.

Siguiendo con el ejemplo de CodeWarrior, este compilador genera en muchas ocasiones un código muy diferente al que generaría g++. Y conocer los detalles de la susodicha generación es vital en desarrollo de videojuegos de consola (y en otros tipos de desarrollo, claro está).

Cita de: Mars Attacks en 28 de Mayo de 2009, 02:18:27 PM
-Limitado significa que no dispones de la forma de llevar a abo operaciones que sí podrías hacer con otros lenguajes, y lento significa que la ejecución (interpretada o compilada) del algoritmo implementado en ese lenguaje tarda más en realizarse que con su implementación en otro lenguaje. Por lo general, cuanto más limitado y lento sea un lenguaje más se han esmerado en que su productividad sea mayor.

Como dije anteriormente, la definición de 'limitado' y de 'lento' es enormemente relativa. Y como dije anteriormente también, un lenguaje no es lento ni rápido per se. Y de ahí que decir que "C++ es rápido" o "Python es lento" no tiene sentido alguno.
#13
Pues deberias haber cogido algo de experiencia. Porque no has sido capaz de contrarrestar ninguno de los argumentos que te he dado con un mínimo de lógica, conocimiento y solvencia técnica, y tus respuestas han sido de corte verdulero y salivante. De chavalín subidito, vamos.

Pero oye, la vida sigue, supéralo.
#14
Ha quedado muy claro, Yotes, y eres extremadamente caballeroso (y me parece genial, por supuesto). En cualquier caso, la decisión es la correcta, y te ahorrará disgustos innecesarios.

Sólo lo decía para minarle un poco el ego al chico.
#15
Excelente decisión, Yotes. Ignorar las barbaridades recomendadas por Hans es la decisión más inteligente que podías haber tomado.





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.