diferencia entre y

7 minutos de lectura

cuando uso malloc en un programa en C, recibo una advertencia:

warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default]

entonces puedo incluir <malloc.h> o <stdlib.h> para deshacerse de la warning aunque también funciona sin él.

Así que me preguntaba cuál es la diferencia entre estos encabezados y cuál hace gcc enlaces cuando no incluyo nada?

(Estoy usando ubuntu 12.04 64-bit con gcc 4.6.3)

avatar de usuario
Basile Starynkevitch

los <malloc.h> El encabezado está en desuso (y es bastante específico de Linux, en el que define no estándar funciones como centro comercial(3)). Utilizar <stdlib.h> en cambio, si simplemente necesita malloc(3) y funciones estándar relacionadas (p. ej. free, calloc, realloc ….). Darse cuenta de <stdlib.h> es definido por C89 (y posteriores) estándares, pero no <malloc.h>

Examinar /usr/include/malloc.h encontrará allí algunas funciones no estándar (por ejemplo, malloc_stats(3)etc…) – además de malloc….

Y gcc no vincule archivos de encabezado, sino bibliotecas. Lea el libro de Levine sobre enlazadores y cargadores para más.

Si no incluye ningún encabezado (y no declara explícitamente malloc usted mismo, lo que sería una mala idea), malloc se declara implícitamente que devuelve algunos int valor (que es incorrecto). Te invito a pasar por lo menos el -Wall bandera a gcc al usarlo.

También podrías pasar -v para gcc para entender los programas reales involucrados: cc1 es el compilador propiamente dicho (que produce código ensamblador), as el ensamblador, ld el enlazador y recoger2 una utilidad interna que invoca al enlazador.

  • Sí, supongo que vincular era el término equivocado. Quería preguntar cómo gcc encontrar malloc función cuando no incluyo ningún encabezado?

    – ninguna

    19/10/2012 a las 11:35

  • Vincular es el buen término. Pero el enlazador no conoce la firma de las funciones de C, solo sus nombres. Solo el compilador propiamente dicho (cc1 iniciado por gcc) se preocupan por el tipo de firma de las funciones.

    – Basile Starynkevitch

    19/10/2012 a las 11:37

  • <malloc.h> puede estar activo (encabezado existente) y obsoleto (no recomendado)

    – Basile Starynkevitch

    8 de noviembre de 2015 a las 14:47

  • Sorprendentemente, memalign() es una de las funciones no estándar declaradas en malloc.h. No es parte de la biblioteca estándar de C.

    – Joel Cunningham

    2 de diciembre de 2015 a las 20:02


  • @JoelCunningham: Eso es porque los únicos nombres estandarizados son posix_memalign (POSIX) y aligned_alloc (C11). memalign en sí mismo es “obsoleto y no estándar”.

    – ShadowRanger

    12 de febrero de 2016 a las 23:26

avatar de usuario
nos

stdlib.h es un encabezado C estándar que declara, entre otras cosas, el malloc(), calloc(), free() funciones Este es el encabezado que debe incluir.

malloc.h es un encabezado no estándar, que se encuentra en muchos sistemas donde a menudo define funciones adicionales específicas para la implementación de malloc utilizada por esa plataforma.

Si no incluye ninguno de estos, no hay ningún valor predeterminado; sin embargo, si llama malloc() sin una declaración previa de la función malloc, C asumirá que la función prototipo es int malloc();, que a menudo es incorrecto. Además de los encabezados, los compiladores de C normalmente se vinculan a una biblioteca estándar, por ejemplo, glibc en Linux, donde reside la implementación de malloc.

Tenga en cuenta que hay una diferencia entre los archivos de encabezado y las bibliotecas. Los archivos de encabezado declaran cosas, como estructuras y prototipos de funciones. Las bibliotecas contienen la implementación, el código compilado. Usted enlaza a la biblioteca, y usted #include archivos de cabecera.

avatar de usuario
steve jesop

Los encabezados declaran diferentes conjuntos de funciones, pero ambos declaran hacia adelante malloc.

Si no incluye ninguno de ellos, entonces no tiene un prototipo para malloc, de ahí la advertencia. Pero se vincula contra la misma función independientemente, porque solo hay una malloc función. Solo se declara hacia adelante en dos lugares. Las declaraciones hacia adelante no están ahí para ayudar a vincular contra el malloc función, están ahí para que el compilador pueda emitir el código correcto alrededor de la llamada, para especificar los argumentos y leer el valor de retorno.

Tenga en cuenta que <malloc.h> no es un estándar incluido. no creo stdlib.h alguna vez incluye malloc.h en GCC, pero puede imaginar que podría, ya que esa es una forma de proporcionar la declaración necesaria.

  • solo para que quede claro, no me da una error pero un warning. El programa funciona bien sin que yo incluya nada.

    – ninguna

    19/10/2012 a las 11:33

  • @gokcehan: Sin embargo, deberías prestar atención a la advertencia. Hay un error real que puede ocurrir como resultado de llamar malloc sin un prototipo en el alcance, y la advertencia es su defensa contra ella. stackoverflow.com/questions/605845/…. Si su programa funciona, es solo porque tiene suerte con respecto a los detalles de la convención de llamadas en esta implementación: el mismo código puede fallar cuando se compila para Linux en alguna otra CPU.

    –Steve Jessop

    19/10/2012 a las 11:35


<malloc.h> no es un encabezado estándar y, por lo tanto, no es portátil. El estándar pone malloc() et al. en <stdlib.h>.

avatar de usuario
david c

Otros ya han discutido las diferencias entre y

En cuanto a la advertencia cuando no se incluye ninguno, esa es la definición de cómo funcionan las funciones de C. Una función sin prototipo (que es lo que tiene cuando no declara el suyo propio y no incluye un encabezado con uno) se trata como una función con un int tipo de retorno y un no especificado lista de argumentos

El compilador realizará promociones predeterminadas (p. ej., flotante a doble y otras) y se llamará a la función. Si el número de argumentos utilizados por la función es diferente del número pasado, o si los tipos de argumento después de las promociones predeterminadas no son compatibles con la implementación de la función, se trata de un comportamiento indefinido.

Ver ISO 9899:1999 (C99) §6.5.2.2, ¶ 6:

Si la expresión que denota la función llamada tiene un tipo que no incluye un prototipo, las promociones de enteros se realizan en cada argumento, y los argumentos que tienen tipo float son promovidos a double. Estos se llaman los promociones de argumento predeterminado. Si el número de argumentos no es igual al número de parámetros, el comportamiento no está definido. Si la función se define con un tipo que incluye un prototipo, y el prototipo termina con puntos suspensivos (, …) o los tipos de los argumentos después de la promoción no son compatibles con los tipos de los parámetros, el comportamiento no está definido. Si la función se define con un tipo que no incluye prototipo, y los tipos de los argumentos después de la promoción no son compatibles con los de los parámetros después de la promoción, el comportamiento es indefinido, excepto en los siguientes casos:

  • un tipo promocionado es un tipo entero con signo, el otro tipo promocionado es el tipo entero sin signo correspondiente, y el valor se puede representar en ambos tipos;
  • ambos tipos son punteros a versiones cualificadas o no cualificadas de un tipo de carácter o void.

En el caso de llamar malloc() sin un prototipo, esto tiene el potencial de ser muy malo. malloc() acepta un size_t argumento y devuelve un void * puntero. Si el resultado de la promoción predeterminada de su argumento entero produce un número entero diferente en tamaño a size_t, tendrá un comportamiento indefinido. Y si int es un tamaño diferente de void * (por ejemplo, en sistemas de 64 bits, donde int suele ser de 32 bits y void * será de 64 bits), el puntero devuelto estará desordenado.

avatar de usuario
bmargulies

Para aprender la diferencia, debe leer su contenido por sí mismo.

Por defecto, gcc no lee ninguno.

Cuando los leas, verás que declaran malloc diferentemente.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad