Importancia del prototipo de función en C

El prototipo de función le dice al compilador sobre una serie de parámetros, la función toma tipos de datos de parámetros y devuelve el tipo de función. Al usar esta información, el compilador verifica los parámetros de la función y su tipo de datos con la definición de la función y la llamada a la función. Si ignoramos la función prototipo, un programa puede compilar con una advertencia y puede funcionar correctamente. Pero a veces, dará un resultado extraño y es muy difícil encontrar tales errores de programación. Veamos con ejemplos
 

C

#include <errno.h>
#include <stdio.h>
 
int main(int argc, char *argv[])
{
    FILE *fp;
 
    fp = fopen(argv[1], "r");
    if (fp == NULL) {
        fprintf(stderr, "%s\n", strerror(errno));
        return errno;
    }
 
    printf("file exist\n");
 
    fclose(fp);
 
    return 0;
}

El programa anterior verifica la existencia de un archivo, provisto desde la línea de comando, si existe un archivo dado, entonces el programa imprime «el archivo existe», de lo contrario, imprime un mensaje de error apropiado. Proporcionemos un nombre de archivo, que no existe en un sistema de archivos, y verifiquemos la salida del programa en la arquitectura x86_64. 
 

[narendra@/media/partition/GFG]$ ./file_existence hello.c
Segmentation fault (core dumped)

Por qué este programa falló, en su lugar debería mostrar un mensaje de error apropiado. Este programa funcionará bien en la arquitectura x86 pero fallará en la arquitectura x86_64. Veamos qué estaba mal con el código. Revise cuidadosamente el programa, deliberadamente no he incluido el prototipo de la función «strerror()». Esta función devuelve «puntero al carácter», que imprimirá un mensaje de error que depende de errno pasado a esta función. Tenga en cuenta que la arquitectura x86 es un modelo ILP-32, lo que significa que los números enteros, los punteros y los largos tienen un ancho de 32 bits, por eso el programa funcionará correctamente en esta arquitectura. Pero x86_64 es el modelo LP-64, lo que significa que los punteros largos y de 64 bits de ancho. En lenguaje C, cuando no proporcionamos un prototipo de una función, el compilador asume que la función devuelve un número entero. En nuestro ejemplo, no hemos incluido el archivo de encabezado «string.h» (el prototipo de strerror se declara en este archivo), por eso el compilador asumió que la función devuelve un número entero. Pero su tipo de retorno es un puntero a un carácter. En x86_64, los punteros tienen un ancho de 64 bits y los enteros tienen un ancho de 32 bits, es por eso que al regresar de una función, la dirección devuelta se trunca (es decir, una dirección de 32 bits de ancho, que es el tamaño del entero en x86_64) que no es válida y cuando tratamos de desreferenciar esta dirección, el resultado es una falla de segmentación.
Ahora incluya el archivo de encabezado «string.h» y verifique la salida, el programa funcionará correctamente. 
 

[narendra@/media/partition/GFG]$ ./file_existence hello.c
No such file or directory

Considere un ejemplo más. 
 

C

#include <stdio.h>
 
int main(void)
{
    int *p = malloc(sizeof(int));
 
    if (p == NULL) {
        perror("malloc()");
        return -1;
    }
 
    *p = 10;
    free(p);
 
    return 0;
}

El código anterior funcionará bien en el modelo IA-32 pero fallará en el modelo IA-64. El motivo de la falla de este código es que no hemos incluido un prototipo de la función malloc() y el valor devuelto está truncado en el modelo IA-64.
Este artículo fue compilado por Narendra Kangralkar . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *