Hace 3 años | Por --681978-- a medium.com
Publicado hace 3 años por --681978-- a medium.com

Durante muchos años fui feliz como programador principalmente en dos idiomas. Use Python para casi todo y desplácese hasta C cuando realmente necesite el rendimiento.

Comentarios

t

#9 A ti te van a vacunar este mes, si no te han vacunado ya.

ccguy

#10 estoy Vacunado hace tiempo, pero porque aquí sobran vacunas 😊

s

#10 algunos por aqui trabajamos en su dia con C++ y ensamblador (si si, ensamblador de 8086 en un entorno productivo, bueno, en mas de uno, y no hace tanto tiempo.... cajeros automáticos con OS2 WARP programados en Java y C++ (+ ensamblador) , accediendo con JNI.... qué tiempos de dejarse las pestañas... vivan los post-it's lol

c

#9 Pues la diferencia no es tan grande como crees. Si tienes experiencia, claro.
De todos modos llevo usando IDES desde el Turbo C y el Turbo Pascal.

El Delphi existe desde 1995, 26 años.

ccguy

#11 Delphi era de bastante alto nivel para su época. Nada que ver con escribir aplicaciones Windows a pelo.

c

#14 El API de Windows era un verdadero infierno.

Y siguen con la mania de los nombres funcionEstupendaQueHaceUnaCosayOtraMasChaChiPirulifnc

DangiAll

#9 Los programadores de verdad usan vi.


https://xkcd.com/378/

ccguy

#23 neovim más bien
Que con coc es un IDE bastante decente

D

#9

vim autocompleta.

Sobre Google, a veces es mierda y lo que es peor, la documentación está desfasada y en vez de solucionar el problema te crea 20 más.

Pero claro, para eso necesitas páginas man decentes, como las de openBSD.

ccguy

#16 pero es que hay memoria que reservas tú pero que no tienes que liberar tú y al revés, para empezar.

Por no hablar de referencias circulares o pasadas a otros componentes, errores lógicos, etc.

En fin, valgrind es popular por algo. Y rust.

No me vas a convencer de que es fácil no tener leaks.

c

#20 pero es que hay memoria que reservas tú pero que no tienes que liberar tú y al revés, para empezar.
Lo que hablábamos antes: Documentación de las funciones. En la documentación deben decir que "me pasas un buffer dinámico y yo lo libero". De todos modos esa es una mala costumbre.

No me vas a convencer de que es fácil no tener leaks.
No es tan difícil como lo pintais. El problema principal es el uso de librerías de terceros, sobre las que no tienes control.

Si, valgrind es útil. Porque la posibilidad de leaks existe. Pero NO es malo que exista, la alternativa es perder el control sobre el uso de la memoria y la destrucción de los objetos.

ccguy

#21 no sé, programas en C hay millones, detrás de muchos están los mejores programadores posibles y todos han tenido leaks. Algunos masivos como Firefox durante años. Manda tu CV a Mozilla 😊

D

#22 Firefox está escrito en C++.

ccguy

#4 hombre, vas a ser tú él único programador sin leaks 😊

c

#8 Hombre, si no te apuran con los tiempos y estás programando en C, no es difícil no tener Leaks.

Simplemente debes ser consciente de lo que estas haciendo (y tener cicatrices de pelearte con ellos, claro).

Lo que si es cierto, y es clave ser consciente de ello, es que como se te escape uno vas a sudar tinta...... En C++ es bastante sencillo no tenerlos.

ccguy

#12 en cuanto empieces a pasar o recibir punteros de librerías, hacer copias de bloques de memoria por razones varias, funciones que tienen que abortar pronto por errores del sistema, etc...

Sinceramente creo que quien diga que es fácil no tener ningún leak en un programa no trivial en C o no ha programado mucho o es un insconciente.

c

#13 en cuanto empieces a pasar o recibir punteros de librerías
Es cierto que las librerías mal documentadas son un problema.

hacer copias de bloques de memoria por razones varias,
Ahí no hay problema

funciones que tienen que abortar pronto por errores del sistema, etc...
Ahí las excepciones han ayudado mucho. Pero sí, es una de los peores problemas.

Sinceramente creo que quien diga que es fácil no tener ningún leak
Digamos "fácil". No es para tanto como se dice todo el tiempo. Y sigo pensando que el recolector de basura NO es una buena solución.
La mejor solución es programar bien.

Si reservas, liberas.

s

#16 LIBERTAD, LIBERTAD!!! Es mi memoria y la gestiono como quiero

Ovlak

#13 insconciente
No soy ni capaz de leerlo lol lol

D

#13 Valgrind, y para el resto fuzzers automáticos.

D

#13 #12 O igual hay que programar con menos pijadas, líneas de código y/o tochos burros como Python & C++ & CUDA & Paraview en un cluster nvidia tesla k40 de 2880 núcleos cuando la misma funcionalidad se consigue en C y un BUEN nivel de matemáticas simplificando ecuaciones diferenciales para hacer en segundos lo que el dicho cluster con CUDA tarda meses. http://phroxy.z3bra.org/bitreich.org:70/0/con/2020/rec/energy-efficient-programming.md

ccguy

#32 no sé si tu principal trabajo es con ecuaciones diferenciales.

CUDA se usa para programar GPUs (y es un superset de C) y no hay matemáticas que vayan a resolver mágicamente la necesidad de paralelismo masivo.

D

#38 No hablo de C, hablo de usar maquinones para tareas que por no tener nociones suficientes de las operaciones que hay debajo, se matan moscas a cañonazos.
Como lanzar el Octave para resolver (verificar) una ecuación en vez de un CAS como Mathomatic o algo más ligero.

D

#12 ¿¿¿¿Lo queeeee????

En cuanto tienes alguna función con un switch, o un par de ifs, es facilísimo que se te escape un puntero.

c

#26 Hombre, también es fácil que no se te escape si tienes un poco de cuidado.

Y cuando se.programa se debe poner MUCHO cuidado.

Es mucho mas fácil y peligroso pasarte del final del área de memoria y no se habla tanto de eso.

D

#27 Y yo te digo que no es tan sencillo. Llevo programando décadas, y en cuanto el proyecto se complica un poquito, es fácil que en algún punto se te escape. Ejemplo: hace un par de años hice un proyecto de tamaño medio para un microcontrolador, en C, y por diversos motivos no me quedó otra que usar memoria dinámica (a pesar de que se recomienda no usarla en proyectos de microcontroladores... ¡pero es que si no, sencillamente era imposible hacer todo lo que necesitaba!); y tuve buen cuidado de definir unas reglas claras: cada función tenía que hacerse cargo de cualquier bloque de memoria que crease o recibiese: bien liberándolo, bien pasándoselo a otra función (que sería entonces la encargada de liberarlo), o bien devolviéndolo a la función llamante (con lo que le pasaría a ésta la responsabilidad de liberarlo). Tiempo después, descubrí que estas eran las mismas reglas de gestión de memoria de RUST, con la excepción de que RUST también permite "prestar" un bloque de memoria, con lo que la función que lo recibe no debe liberarlo. La cuestión es que, a pesar de hacerlo así, hubo un día que tenía un memory leak y, sencillamente, no había manera de encontrarlo. Y fíjate que las reglas son sencillas, y analizando cada función deberías poder encontrar en cual está. Pues nada, no había manera. Por supuesto, hablo de un programa de más de doce mil líneas, y un par de cientos de funciones. Al final tuve que usar un analizador estático (modificando además mi código para que éste entendiese mis reglas) para descubrir que en una de las funciones, en uno de los "ifs", se me había olvidado liberar el bloque de memoria. Y además, de paso, me encontró un par de errores extra.

Pero ya ves que aún con unas reglas claras y metódicas, puede escapársete en un punto un mémory leak y ser incapaz de encontrarlo manualmente. Simplemente porque somos humanos.

c

#33 Claro que puede pasar. Pero en general que otra función tenga que liberar memoria que no reserva es algo que hay que documentar muy bien en la función que hace la reserva y poner especial cuidado cuando se usa.

Si una función "reenvia" ese bloque a todos los efectos es como si lo reservara él, y también hay que tener cuidado.

Que se lo devuelva a la función llamante no es problema.

Los dos primeros puntos requieren MUCHA atención. Dicho eso, bugs lógicos siempre hubo y siempre habrá.
En todos los lenguajes

Como he dicho antes es peor el buffer overflow.

D

#34 Esa es la cuestión: en mi código estaba perfectamente documentado, pues no había excepciones. Pero aún así, en un código con cientos de funciones y ejecución mínimamente alambicada (vamos, que una función puede salir en varios puntos en lugar de salir siempre en la última línea de la función) es fácil que se te pase. Y depurarlo no es trivial.

Valgrind y un buen analizador estático es imprescindible (en mi caso tuve que añadir un "simulador" para poder correr el código en el PC y poder pasarle Valgrind, pero desde luego valió la pena).

c

#35 No. Depurarlo no es trivial. Y Valgrind es útil.
Por eso hay que poner MUCHO cuidado.

Pero no es ninguna tragedia dadas las ventajas.

D

#36 Que sí, pero es lo que digo desde el principio: que no es tan sencillo como "poner cuidado y ya no cometes errores".

pitercio

Estaba avisado hace años

r

#6 se podrían juntar con estos y hacer un festival:

squanchy

Ah, aquellos maravillosos años del c++, cuando al salir del programa te daba un error de memoria no liberada y tenías que dejarte los ojos buscando el puntero sin liberar.

M

#1 Aquellos maravillosos años ya son historia. Desde C++11 (y C++14, C++17 y C++20) ya tienes Smart pointers (std::unique_ptr, std::shared_ptr, etc) que evitan esa búsqueda del puntero sin liberar como dice en el artículo.

squanchy

#2 Qué bien. Hace un par de años ayudé a un chaval con unas prácticas de programación concurrente, y vi que usaba una librería para semáforos y similares. Una maravilla. Yo es que soy de los tiempos del borland c en MS-DOS, y más tarde Visual C++. Eran tiempos duros para programar.

c

#3 Programar es programar.

Antes y ahora.
No ha cambiado nada. Es igual de duro o de fácil que antes.

c

#1 Eso se soluciona dejando el cerebro cuando programas.

Odio los recolectores de basura. Yo se cuando debo o no debo liberar la memoria.