Hola y bienvenidos.
En esta conferencia me gustaría hablar de la depuración.
Este es un concepto muy importante que hay que entender específicamente, hay que entender algunas de las herramientas
y algunos de los métodos que se pueden emplear para encontrar y corregir errores.
La depuración es el proceso de encontrar y corregir errores en un programa.
Normalmente errores lógicos.
Y te voy a decir la diferencia entre errores lógicos y de sintaxis, pero también puede incluir errores de sintaxis
del compilador.
Es todo el proceso de errores de sintaxis.
Depurar es entender lo que te dice el compilador.
Siempre hay que centrarse en solucionar el primer problema detectado.
Quiero repasar algunos de los errores y advertencias comunes del compilador que puedes obtener, pero una
de las cosas que siempre quieres saber sobre el compilador es que el compilador puede darte una serie
de errores.
Siempre hay que centrarse en el primer error porque ese primer error puede dar lugar a otros errores.
Así que puede ser muy engañoso si usted ve cinco errores en un en un programa que el compilador le está diciendo, usted podría tener sólo
un error y que el primer error podría estar causando los otros errores.
Por eso es importante fijarse siempre en el primer error y corregirlo primero.
En este ejemplo muy simplista, tenemos múltiples errores en este código.
No tenemos una.
No tenemos un corchete izquierdo inicial, llave rizada.
No tenemos punto y coma.
Devolvemos una cadena.
Y así, cuando guardamos esto y vamos a compilarlo y en realidad ver algunos errores en
rojo, cuando vamos a compilarlo, en realidad nos dice que tenemos tres errores.
Nunca debe seleccionar sólo el último error de la línea siete, aunque en este caso se trate de un error real.
Siempre quieres arreglar el primer error.
Así que ves el primer error listado aquí y arreglas ese primer error y luego recompilas y lo ejecutas de nuevo.
Pero la razón para hacer esto es sólo para arreglar ese error de nivel superior es porque ese error puede causar otros
problemas.
Por lo tanto, hay que centrarse siempre en solucionar ese primer error. La depuración y el proceso de búsqueda y solución de errores pueden ser muy
complejos, desde la búsqueda de errores sencillos hasta la recopilación de grandes cantidades de datos para su análisis.
Todo depende.
A veces no se dispone de más información que el registro, y en ese caso hay que analizar
las cosas.
A veces tendrás fallos que no se pueden repetir.
No se puede reproducir porque ocurre en muy raras ocasiones.
Suele ser cuando hay que analizar registros o alguna variación de eso.
La capacidad de depuración de un programador es una habilidad esencial.
Se trata de una habilidad para resolver problemas que puede ahorrarte mucho tiempo y dinero.
Así que es una habilidad importante que hay que aprender.
Es una habilidad importante que hay que desarrollar.
Requiere práctica.
No va a venir a ti sin más.
Hay ciertas técnicas que puedes aplicar y métodos que puedes aplicar para mejorar
tu depuración.
Conozco a bastantes desarrolladores que son realmente buenos escribiendo código de software.
Entienden muy bien el lenguaje, pero sus habilidades de depuración son muy pobres.
Pueden tener un error y su primera inclinación para resolver ese error es realmente un poco fuera de lugar.
Y, de nuevo, esto se consigue con la práctica.
Cada vez se te dará mejor depurar y entender cómo encontrar y solucionar problemas, pero es
algo que también tienes que aprender.
La fase de mantenimiento es la más costosa del ciclo de vida del software.
La fase de mantenimiento se produce después de lanzar el producto y ahora hay que mantenerlo.
Mantenerlo significa corregir los nuevos errores que surjan y añadir nuevas funciones.
Así, por ejemplo, cuando Windows lanza un nuevo sistema operativo como Windows 10, no han terminado de
producir ese software.
Estará en el campo probablemente diez años.
Y sigue siendo responsabilidad de Microsoft cuando aparecen nuevos fallos o encuentran nuevos fallos para ese software para solucionarlo.
Y por eso lanzan actualizaciones automáticas y hacen cosas así.
Y también se darán cuenta de que el sistema operativo sacará nuevas funciones a medida que cambie
el mercado y la tecnología.
Así que el mantenimiento es muy importante.
Por eso es muy importante encontrar y corregir los errores.
Comprenda, no obstante, que los fallos son inevitables.
Todos los programas tienen fallos.
Nadie puede escribir un código perfecto y ni siquiera se trata necesariamente de escribir un código perfecto.
Es que las cosas cambian con el tiempo.
Así que eso también puede dar lugar a fallos.
Hay que entender que el hecho de que un programa tenga errores no significa que esté mal escrito.
Es algo inevitable.
Así que está bien tener fallos, ya sabes, cuando los encuentras y los arreglas, es aún mejor porque realmente
sientes que estás logrando algo.
Problemas comunes.
Y vamos a hablar más sobre problemas específicos relacionados con ver.
Pero los problemas más comunes cuando intentas depurar son los errores lógicos.
Los errores lógicos no tienen que ver con el tipo opuesto de errores de sintaxis que su código realmente compila.
Funciona, pero no hace lo que debe hacer.
Así que hay algún tipo de lógica o funcionalidad prevista que es incorrecta.
Tal vez usted tiene una declaración IF y usted está saltando en esa declaración if en la condición equivocada.
Puede que tengas un bucle y éste no se esté ejecutando el número de veces correcto o que no estés ordenando correctamente.
La funcionalidad está rota, pero el compilador dice, Hey, todo se ve bien.
He aquí un ejemplo de error lógico.
Un error lógico se produce cuando la sintaxis es correcta, pero los resultados deseados no son correctos debido a algún tipo de problema
lógico.
Así que en este código ves que el bucle for tiene un punto y coma al final que es sintácticamente correcto.
Pero esperas que este bucle for se ejecute cinco veces.
Pero no lo es.
Sólo va a un tiempo de ejecución.
Así que si decimos construir y construir este proyecto, vemos una advertencia, que es agradable y siempre debe fijar todas sus advertencias.
Pero se compiló correctamente.
Así que cuando ejecutamos este proyecto, te darás cuenta de que en realidad sólo se ejecuta una vez e
imprime Hola Mundo una vez.
Este es un ejemplo de error lógico.
Los errores de sintaxis están directamente relacionados con el compilador.
Son cosas que no siguen las reglas de la lengua.
No se pone punto y coma al final de una frase.
No tienes un final, ¿verdad?
Paréntesis con izquierda, paréntesis.
Te falta un soporte.
No estás usando la palabra clave correcta, cosas así.
Los errores de sintaxis suelen ser causados por el compilador Los errores lógicos van a ser causados por el programador
durante la fase de pruebas.
La corrupción de la memoria también es un problema común, especialmente en C.
Si no estás liberando tu memoria después de asignarla correctamente, puedes tener
cosas como referencias colgantes y también puedes tener problemas de memoria relacionados con la memoria que no está siendo utilizada.
Puede haber fugas de memoria.
He aquí un ejemplo de error de memoria.
En este código en particular, en realidad tenemos una fuga de memoria, por lo que no hemos hablado de punteros todavía.
No hemos hablado de la asignación dinámica de memoria.
Pero en C puedes asignar memoria mientras tu programa se está ejecutando.
Puedes utilizar una función malloc.
Y aquí estamos marcando, estamos asignando memoria, pero nunca la estamos liberando.
Así que podemos construir este código y podemos ejecutarlo y todo está bien para ir, pero en realidad no estamos liberando este
error.
Así que lo que tendríamos que hacer realmente para corregir este error de memoria es que tendríamos que decir free y luego tenemos
que decir free y X para liberar ese puntero.
Pero cuando asignas memoria, no la liberas.
Es una fuga de memoria.
Y luego otro ejemplo sería si no asignamos la memoria, si creamos un puntero y luego tratamos de asignarlo,
vamos a tener corrupción de memoria porque esa memoria no tiene ninguna asignación para ella y estamos
tratando de asignarle un valor.
Así que eso es sólo un poco, un poco de algunos ejemplos para la memoria, la corrupción, el rendimiento y la escalabilidad.
Esto podría ser un problema cuando tu funcionalidad está pensada tal cual y tu código sintácticamente
es correcto, pero no es muy eficiente o no tienes el hardware para soportarlo.
Así que si estás ejecutando un servidor y no tienes suficiente hardware para soportar todas las peticiones,
va a funcionar muy, muy lento.
O si escribiste tu programa para que funcionara con diez usuarios, pero cuando hay muchos, quizá
no es tan rápido porque la base de datos se atasca o lo que sea.
El código funciona, pero no está diseñado correctamente para manejar muchas, muchas cantidades de usuarios o lo que
sea el caso.
Falta de cohesión.
Esto puede ser un problema en su código que reduce la calidad relacionada con su código está haciendo demasiado o una función
está haciendo demasiado.
No es un enfoque único o incluso una aplicación tiene demasiada funcionalidad, tiene características
que nunca se utilizan, y por lo tanto esto probablemente requeriría un rediseño.
He aquí un ejemplo de programa no modularizado, no cohesionado.
Tienes una gran función que está haciendo demasiadas cosas cientos de líneas de código, miles de líneas
de código.
Quieres dividir una función en funciones auxiliares, módulos separados.
Eso hace que tu programa sea mucho más cohesivo, más fácil de mantener.
Así que en lugar de tener como un gran método principal que hace la inicialización de lectura de entrada, encontrar algunos,
encontrar la diferencia, encontrar producto, encontrar cociente, usted podría crear todo este código y lo puso en los
módulos de ayuda y separar el código y por lo que la separación puede ayudar a encontrar y corregir los errores mucho más fácil.
La cohesión es siempre importante en C y normalmente se resuelve cuando se tiene una alta cohesión proporcionando métodos
ayudantes.
Acoplamiento apretado.
Esto también tiene que ver con la calidad del código.
Aquí es donde tienes un montón de dependencias.
El acoplamiento es diferente de la cohesión.
La cohesión es su único objetivo.
El acoplamiento se produce cuando existen dependencias entre funciones u objetos.
Hablamos de acoplamiento, hablamos de variables globales.
Si una variable global se utiliza en muchas funciones diferentes, puede causar dependencias entre
esas funciones.
Así que lo que usted quiere esforzarse cuando se escribe el código y que está escribiendo código de alta calidad
es que usted quiere tener muy alta cohesión y muy bajo acoplamiento.
El proceso de depuración.
Lo primero que tienes que hacer antes de encontrar y solucionar cualquier error es entender
el problema.
Esto se relaciona con el hecho de no lanzarse y empezar a mirar el código, sentarse con el probador, comprender
los requisitos, entender lo que está pasando.
Porque si no entiendes lo que está pasando, ni siquiera vas a ser capaz de hacerlo.
Ni siquiera deberías intentar resolverlo.
Una vez que entiendas el fallo, intenta reproducirlo porque reproducirlo puede ayudarte a reunir más
información.
No siempre es posible reproducir los errores porque pueden producirse en circunstancias realmente raras.
Así, por ejemplo, los errores que tienen como condiciones de carrera o incluso corrupción de memoria sólo pueden ocurrir
en casos de uso muy específicos y pueden ser problemas intermitentes.
¿Y es así?
Y no se puede reproducir.
Cada vez será más difícil de depurar.
Si eres capaz de reproducirlo, normalmente podrás reunir suficiente información para solucionarlo.
La mayoría de los problemas son solucionables.
Además, puedes tener problemas de no poder reproducir un problema si tienes un entorno multihilo,
procesos paralelos o problemas de hilos.
Esos también son muy difíciles de depurar, pero definitivamente tratar de reproducirlo una vez que haya descubierto
lo que el problema es en realidad en términos de que usted es capaz de entender la una vez que usted es capaz de reproducir, si no
lo eres, entonces usted quiere tratar de acercarse a aplicar algún tipo de divide y vencerás.
Hay que intentar aislar el fallo, simplificar el problema, porque ser capaz de reducir va a devolverte información,
pero puede que no te diga necesariamente en qué parte del código está el fallo.
Así que lo que puedes hacer para tratar de simplificar el problema es eliminar partes del caso de prueba original para que no
estés probando demasiado.
Puedes aislar aún más el problema diciendo: "Oh, sólo ocurre en esta situación concreta".
También puedes comentar el código.
Hablamos de funciones que sólo tienen stubs y no tienen implementación.
A veces se emplea en las pruebas para poder limitar el conjunto de problemas.
Además, si comentas el código, vas a tener menos código en el que el fallo pueda ocurrir realmente.
Así que a medida que comentas el código o retiras los cambios, el fallo puede desaparecer y si el fallo desaparece, eso
te dice que el código que comentaste puede haber sido la causa.
Sin embargo, lo que quieres hacer es convertir un programa grande en muchos programas pequeños, ya sea
mediante pruebas o comentarios.
Otra técnica común es tener pruebas unitarias alrededor de su código.
Si una prueba unitaria falla, eso puede indicarle exactamente dónde puede estar la lógica o el problema en su código.
Una vez que aísles el fallo, eso te ayudará a encontrar el origen del problema en el código, el código específico que
está causando el problema.
A veces, esto empleará el uso de herramientas de depuración como un depurador.
Vamos a hablar de un depurador en concreto, pero por lo general, dependiendo de qué IDE de desarrollo integrado
que utilice, hay depuradores que vienen con el IDE.
También hay depuradores que pueden aterrizar de forma autónoma.
El depurador más importante que vamos a utilizar para la programación en C se llama GDB.
Es el depurador de GNU, una buena herramienta gráfica con la que puedes detener la ejecución
de tu programa y añadir puntos de interrupción.
Y luego, al detener la ejecución, puedes ir línea por línea en tu código y mirar el valor de las variables.
Así podrás ver exactamente lo que ocurre en tu código mientras se ejecuta.
Es una herramienta inestimable.
Es que es muy útil.
Vamos a ejecutar a través del depurador.
Te mostraré cómo añadir puntos de interrupción.
Te mostraré cómo configurar un reloj para que puedas ver las variables a medida que cambian y también luego paso a paso a través
del código.
Una vez identificado el origen del problema, hay que solucionarlo.
Esto requiere mucha experiencia y práctica.
Aunque hayas encontrado el origen del problema, es posible que no puedas solucionarlo basándote únicamente
en tu experiencia.
Esto a veces incluye el rediseño o la refactorización de otro código que, especialmente con problemas de escalabilidad
o problemas de rendimiento, puede que tenga que rediseñar para permitir que su software sea más escalable.
Así que no siempre es fácil encontrar el problema y solucionarlo.
El problema a veces, especialmente los problemas aún más difíciles como los hilos o el procesamiento paralelo,
son aún más difíciles de solucionar.
Pero a medida que escriba más y más código, esto será más fácil de hacer.
Y por último, tienes que hacer pruebas como un loco.
Prueba siempre muchos límites diferentes.
Casos buenos, casos malos y casos intermedios para verificar que efectivamente has solucionado el problema.
Algunas de las técnicas y herramientas disponibles.
Una herramienta común y muy, muy utilizada es utilizar sentencias print.
Puede utilizar sentencias print para rastrear básicamente su código.
Así que en C puedes usar la sentencia print F y puedes ponerla en varias líneas de tu código para indicar
dónde estás.
Esto también es útil, muy útil cuando tu programa se bloquea.
Puede ayudar a identificar dónde se estrelló.
A medida que vas añadiendo estas sentencias de impresión trazando a través de tu código, puedes añadir salida en las sentencias
de impresión para ver el valor de las variables porque el valor de las variables puede estar afectando al estado y puede estar
causando problemas lógicos.
Así que añadir sentencias print es muy, muy útil.
Puede mostrar el flujo de ejecución y ayudar a aislar el error.
Depuradores como mencioné uno en GDB, esos pueden monitorear la ejecución del programa.
Puedes detenerlo, ejecutarlo línea a línea, reiniciarlo, establecer puntos de interrupción, vigilar variables y memoria.
Muy, muy útil cuando se trata de diagnosticar dónde reside un problema.
Archivos de registro.
Los archivos de registro también son muy útiles, sobre todo para los fallos que no se pueden recrear.
Puedes analizarlos más adelante para ver exactamente qué estaba pasando cuando se produjo el fallo.
Esto significa que, para que sea útil, tienes que proporcionar buenas declaraciones de registro
en tu propio código.
Así que usted puede crear su propio archivo de registro y luego escribir en ese registro como el programa se está ejecutando de modo que si usted tiene
un error, puede enviar esos registros a los desarrolladores.
En Xerox lo empleamos bastante porque, cuando nos encontramos con problemas, no siempre podemos reproducirlos
o pueden surgir sobre el terreno.
Necesitamos poder acceder a esos registros para ver qué estaba ocurriendo cuando se produjo ese fallo.
Software de control.
Hay programas que pueden supervisar y analizar en tiempo de ejecución el uso de la memoria, la amenaza del tráfico de red y la información
sobre objetos.
Esto puede decirte si tal vez estás asignando demasiada memoria y no la estás borrando.
Si tienes una herramienta para el tráfico de red de uso de memoria que puede decirte si estás
enviando demasiados paquetes o si tu software es escalable o no, si tienes un aumento en el tráfico
de red y ves que tu tiempo de respuesta se está degradando.
También puedes monitorizar hilos y objetos de información para el procesamiento paralelo para ver qué está pasando
en ciertos hilos y qué está pasando en otro hilo.
Eso te ayudará a diagnosticar cualquier tipo de problema con las roscas.
Algunas otras herramientas comunes de depuración que puede emplear para encontrar y corregir sus errores.
Puede utilizar la gestión de excepciones.
Muchos lenguajes de programación tienen tratamiento de excepciones.
Desafortunadamente, C no un controlador de excepciones en realidad evitar accidentes y hacer un montón de cosas en tiempo
de ejecución.
No es aplicable a ver, pero sigue siendo bueno entenderlo.
Bloques Trycatch, cosas así.
Analizadores estáticos.
Existen muchos analizadores estáticos disponibles para C.
Analizar el código fuente sin el ejecutable real.
No es necesario ejecutar el programa.
Va línea por línea y examina el código fuente.
Y mientras analiza el código fuente, busca cualquier problema conocido.
Así puede comprobar la semántica.
Puede asegurarse de que.
Ya está.
No tienes variables no inicializadas si estás si estás asignando nueva memoria que la borras.
Si tienes algún código muerto en el que el código no se está ejecutando realmente, puedes eliminar ese código.
También analiza aspectos como las condiciones de carrera y los bloqueos.
Donde yo trabajo empleamos un par de analizadores estáticos.
Tenemos uno llamado Coverity, que es bastante popular, y hay una herramienta de sonar de código que utilizamos también, y vamos a ejecutar
esto en toda nuestra línea de base, todo nuestro conjunto de fuentes.
Y siempre que introduzcamos nuevos archivos y nuevo código, esa herramienta se ejecutará en ese código y será capaz de identificar
problemas inmediatos con el código en cuanto a variables no inicializadas, fugas de memoria y demás.
No analiza la sintaxis.
Para eso está el compilador.
También hay una serie de suites de pruebas que ejecutan un conjunto de pruebas completas de extremo a extremo del sistema que
puede ejecutar en su software.
Las pruebas siempre son importantes, pero si puedes automatizarlas de alguna manera para ejecutar ciertas pruebas cada
vez que haces una nueva compilación, por ejemplo, eso puede ser muy útil y esto realmente puede prevenir errores,
pero también ayuda a diagnosticar errores.
Depurar el programa después de que se haya bloqueado.
Vamos a hablar de algo llamado pila de llamadas.
Este es un mecanismo muy útil de ver, especialmente en un lenguaje como C, donde usted tiene un accidente y todo lo que la única
información que se obtiene es algo así como fallo de segmentación.
Cuando se produce ese fallo, lo que sucede muchas veces, dependiendo de cómo se estrelló, un archivo de núcleo
se genera y se puede analizar el archivo de núcleo para mirar a la pila de llamadas para ver exactamente donde ese programa
murió.
Te dirá la línea de código donde murió el programa.
Y así vamos a aprender sobre la pila de llamadas.
Y en cuanto al análisis de los archivos centrales, es una técnica más avanzada.
Pero en C, se puede generar un archivo de núcleo y analizarlo.
Es una técnica un poco más avanzada, pero es otra forma de depurar el software.
¿Y la prevención de errores?
Sabemos que depurar es encontrar y corregir errores, pero si puedes prevenirlos, mejor aún.
Una de las formas de evitar errores es escribir código de alta calidad.
Muchos ingenieros informáticos no se centran en esto.
Muchos ingenieros de software escriben el código y, mientras funcione, es lo único
que les preocupa, o mientras el resultado sea correcto, se dan por satisfechos.
Pero existe el código de mala calidad y no querrás escribirlo.
He demostrado algo de esto durante las clases, pero cosas como usar nombres de variables significativos son
muy importantes.
O si escribes código ineficiente donde estás usando bucles tal vez más de lo necesario, o usando una sentencia
if o no necesitas hacer eso.
Todas estas cosas constituyen un código de mala calidad.
Si tienes una función que está haciendo otras 100 cosas y no está cohesionada, si tienes 5000 líneas
en una función, si tu código no está organizado de forma modular o si tienes muchas dependencias
entre funciones, de nuevo, todo esto es código de baja calidad y quieres esforzarte por no hacerlo.
Le conviene emplear técnicas en las que su programa esté organizado.
Es fácil de mantener, está muy cohesionado, tiene poco acoplamiento y utiliza nombres de variables significativos.
Muy, muy importante.
De nuevo, es muy importante también porque la fase de mantenimiento es muy, muy cara.
Si escribes código de mala calidad, será mucho más difícil mantenerlo.
Es más difícil aislar los errores y más difícil añadir nuevas funciones.
Así que emplee buenas técnicas de alta calidad al escribir su código.
Pruebas unitarias.
Las pruebas unitarias ayudan enormemente a prevenir errores.
Las pruebas unitarias se ejecutan normalmente de forma automática cuando se compilan las pruebas unitarias pueden ayudar a evitar la regresión.
Es uno de los factores más importantes.
Regresión es cuando escribes código nuevo e introduces un error en algo que antes funcionaba.
Has roto el código antiguo.
No quieres hacer eso.
Si algún software está funcionando y luego algo nuevo que hiciste lo rompió, quieres ser notificado inmediatamente
y las pruebas unitarias pueden ayudar a hacer eso porque las pruebas unitarias se ejecutarán en ese código antiguo y dirán, Hey, esto
estaba funcionando, ahora está fallando.
También puede encontrar errores en el código nuevo antes de que se entregue, porque, de nuevo, se ejecutan después de construir
y le dirá inmediatamente que algo está mal.
Hay un concepto de desarrollo basado en pruebas que se está haciendo muy, muy popular.
Aquí es donde primero se escriben las pruebas y después se desarrolla el código.
Y el objetivo aquí es cuando usted escribe su primera prueba, su prueba está fallando y luego escribir el código para
conseguir que pase.
TDD tiene muchas ventajas y es una forma de pensar inversa.
Normalmente, cuando se escribe código, primero se escribe el código y después se escriben las pruebas.
Pero con TDD, en realidad te da una forma diferente de pensar para que estés trabajando en trozos realmente
pequeños y tiendes a escribir código muy cohesivo y no tienes el código, no tiene un montón de dependencias
porque ¿adivinen qué?
Si eres capaz de probar el código, significa que el código no tiene tantas dependencias.
Si tu prueba unitaria es muy, muy grande y estás simulando todas estas cosas diferentes,
por lo general es un gran indicador de que tu código es muy, muy dependiente de otras cosas.
Así que al emplear TDD, te obliga a escribir código muy poco acoplado que no tiene dependencias y te obliga
a tener tus funciones muy cohesionadas.
TDD tiene muchas ventajas.
También hay que documentarse bien y hacer una planificación adecuada.
No se limite a sumergirse en el código y empezar a aplicarlo.
Escribe tu diseño en un papel.
Utilizar pseudocódigo.
Bien.
Planifique su código.
Si planificas tu código, entiendes los requisitos y tienes un buen diseño bien pensado, puedes
evitar muchos, muchos errores.
Y he mencionado esto a lo largo del curso, pero es muy, muy importante tener un enfoque del tipo
divide y vencerás, trabajar en pequeños pasos y probar constantemente después de cada paso, no escribir 1000 líneas de código
y luego decir, está bien, compilar y probar.
No es un buen planteamiento.
Evite demasiados cambios a la vez.
Cuando realice cambios, aplíquelos de forma incremental, añada un cambio y, a continuación, pruébelos a fondo antes de iniciar
el siguiente paso.
Esto puede ayudar a reducir todo tipo de errores y también limita su conjunto de problemas.
Así, si tienes un error, sabes inmediatamente dónde está en el código porque acabas de compilar
y acabas de añadir esa línea o ese número de líneas.
Una vez más, no puedo enfatizar la importancia de depurar escribiendo código de alta calidad, previniendo errores.
Estas técnicas de resolución de problemas le ahorrarán mucho tiempo y le convertirán en un programador de primer nivel
mucho mejor.
Así que en las próximas conferencias, quiero hablar de algunos de los errores comunes que vemos en el lenguaje de programación
c.
Además, quiero hablar un poco sobre la pila de llamadas.
Quiero ir a través del depurador que le introducen a las opciones de menú y cómo se puede detener y ejecutar relojes
y así sucesivamente.
Y también quiero ayudar a identificar algunos errores comunes del compilador que se ve cómo interpretar los compiladores, advertencias y errores
del compilador.
¿Qué significa que el compilador diga esto?
¿Qué significa que el compilador emita esta advertencia?
Gracias, señor.