UC3M

Grado en Ing. Telemática/Sist. Audiovisuales/Sist. de Comunicaciones

Arquitectura de Sistemas

Septiembre 2017 - Enero 2018

14.12.2. Mensajes más comunes del compilador

A continuación se describen los mensajes más comunes que muestra el compilador. Se ofrecen ejemplos de código para ilustrar las causas del error, pero debe tenerse en cuenta que cada programa tiene una estructura diferente, y por tanto, el error puede aparecer por causas de alto nivel diferentes.

  1. `variable' undeclared (first use in this function)

    Este es uno de los más comunes y a la vez más fáciles de detectar. El símbolo que se muestra al comienzo del mensaje se utiliza pero no ha sido declarado. Sólo se muestra la primera de las apariciones.

  2. warning: implicit declaration of function `...'

    Esta advertencia aparece cuando el compilador encuentra una función que se utiliza en el código y de la que no tienen ningún tipo de información hasta el momento. El compilador asume que la función devuelve un entero, y continúa.

    Estas advertencias son las que se recomienda eliminar antes de probar la ejecución del programa. Dependiendo de la situación, hay varias formas de eliminar este mensaje. El compilador necesita saber cómo se define la función que ha encontrado. Para ello, en un lugar anterior en el fichero se debe incluir, o la definición de la función o su prototipo (el tipo de dato que devuelve, seguido de su nombre, los paréntesis con la definición de los parámetros y un punto y coma).

    Si esta información (la definición de la función) se necesita en múltiples ficheros, entonces, en lugar de escribir la misma información en cada uno de ellos se recomienda incluir el prototipo en un fichero que es luego incluido en donde se necesite a través de la orden #include del pre-procesador. Recuerda que el código de una función sólo puede estar presente en un único fichero de código. Si el compilador se lo encuentra en más de un fichero, entonces se producirá un error por haber definido una función múltiples veces.

    También puede darse el caso de que la información que se solicita esté contenida en un fichero a incluir por tratarse de una función en una biblioteca. Para consultar si la función está en una de las bibliotecas estándar de C se recomienda utilizar el comando man seguido por el nombre de la función. Si es parte de una biblioteca, en la misma página de manual se muestra qué fichero hay que incluir en el código.

  3. warning: initialization makes integer from pointer without a cast

    Esta advertencia nos dice que hemos utilizado un puntero en un contexto en el que se espera un entero. Esto está permitido en C y el compilador sabe qué hacer para traducir el código, pero igualmente se notifica por si se quiere confirmar esta operación mediante un cast. El siguiente código muestra un ejemplo que produce esta advertencia.

    int main (void) 
    {
      char c = "\n";  /* ¿incorrecto? */
      return 0;
    }

    En la primera línea se asigna un puntero a letra (pues una cadena entrecomillada se almacena por debajo como una dirección de memoria, que es la que contiene la primera letra) a una letra. A pesar de que c está definida como una letra, el compilador la trata como un entero, lo cual es legal. La cadena de texto "\n" se toma como un puntero, y de ahí se deriva el mensaje de advertencia. Se está asignando un puntero a una variable que no lo es y que puede ser considerada como un entero, y además, no se está utilizando un cast.

    En la mayoría de los casos esta asignación es en realidad un error del programador y por tanto necesita ser corregido. Pero es posible que se quiera manipular un puntero como un número tal y como se muestra en el siguiente programa:

    int main (void) 
    {
      int value = "\n"; /* Asignación correcta */
      return 0;
    }

    Supongamos que en este caso el programador sí necesita almacenar ese puntero en una variable entera. El compilador igualmente imprime la advertencia. Para confirmar al compilador que realmente este es la asignación que se quiere hacer se puede utilizar un casting, esto es, poner entre paréntesis como prefijo de un símbolo el tipo de datos al que queremos transformarlo. Una vez añadido este prefijo, el compilador entiende que esta asignación es realmente lo que se quiere hacer y no se muestra la advertencia.

    int main (void) 
    {
      int value = (int)"\n"; /* Asignación correcta y confirmada por el programador 
                            mediante el casting */
      return 0;
    }
  4. dereferencing pointer to incomplete type

    Este error aparece cuando se utiliza un puntero a una estructura de datos para acceder a alguno de sus campos, pero el compilador no tiene información suficiente sobre esa estructura de datos. El siguiente programa muestra esta situación:

    struct btree * data;
    int main (void) 
    {
      data->size = 0;  /* Información incompleta */
      return 0;
    }

    La declaración de la variable data como puntero a la estructura btree es correcta. Para declarar un puntero a una estructura no se necesita la definición de la estructura. Pero en la primera línea de la función main ese puntero se utiliza para acceder a uno de los campos de esta estructura. Al no tener esa definición, el error se muestra en pantalla.

    La causa más probable de este error es que la definición de la estructura está en otro fichero, y debe estar presente antes de que un puntero se utilice para acceder a sus campos. Por este motivo, las definiciones de las estructuras se suelen agrupar en ficheros con extensión *.h que son incluidos en los ficheros de código.

  5. warning: control reaches end of non-void function

    Esta advertencia aparece cuando una función se ha declarado como que devuelve un resultado y no se incluye ningún comando return para devolver ese resultado. Por tanto, o se ha definido incorrectamente la función, o se ha olvidado este comando. El compilador igualmente genera el ejecutable y aunque la función no devuelva resultado, el compilador sí devuelve un resultado a la función que ha hecho la invocación.

  6. warning: unused variable `...'

    Esta advertencia la imprime el compilador cuando detecta que una variable ha sido declarada pero no se utiliza en ningún sitio. El mensaje desaparece borrando la declaración.

  7. undefined reference to `...'

    Este mensaje aparece cuando en el código se ha invocado una función que no está definida en ningún lugar. El compilador nos dice que hay una referencia a una función sin definición. Mira qué función falta y cerciórate de que su definición se compila.

  8. error: conflicting types for `...'

    Se han encontrado dos definiciones del prototipo de una función. Una es un prototipo (tipo del resultado, nombre, paréntesis con los parámetros y un punto y coma) y la otra es la definición con el código. La información en ambos lugares no es idéntica y por tanto existe un conflicto. El compilador te muestra en qué linea se ha encontrado el conflicto y la definición previa que ha causado la contradicción.