Saltar al contenido

¿Qué implica “#define _GNU_SOURCE”?

Solución:

Definiendo _GNU_SOURCE no tiene nada que ver con la licencia y todo con la escritura de código (no) portátil. Si tu defines _GNU_SOURCE, conseguirás:

  1. acceso a muchas funciones de extensión GNU / Linux no estándar
  2. acceso a funciones tradicionales que se omitieron del estándar POSIX (a menudo por una buena razón, como ser reemplazado con mejores alternativas o estar vinculado a implementaciones heredadas particulares)
  3. acceso a funciones de bajo nivel que no pueden ser portátiles, pero que a veces necesita para implementar utilidades del sistema como mount, ifconfigetc.
  4. comportamiento roto para muchas funciones especificadas por POSIX, donde la gente de GNU no estaba de acuerdo con el comité de estándares sobre cómo deberían comportarse las funciones y decidió hacer lo suyo.

Siempre que esté al tanto de estas cosas, no debería ser un problema definir _GNU_SOURCE, pero debe evitar definirlo y en su lugar definir _POSIX_C_SOURCE=200809L o _XOPEN_SOURCE=700 cuando sea posible para asegurarse de que sus programas sean portátiles.

En particular, las cosas de _GNU_SOURCE que deberías Nunca los usos son el n. ° 2 y el n. ° 4 anteriores.

Para obtener detalles exactos sobre qué están habilitados por _GNU_SOURCE, la documentación puede ayudar.

De la documentación de GNU:

Macro: _GNU_SOURCE

Si define esta macro, todo está incluido: ISO C89, ISO C99, POSIX.1, POSIX.2, BSD, SVID, X / Open, LFS y extensiones GNU. En los casos en los que POSIX.1 entra en conflicto con BSD, las definiciones de POSIX tienen prioridad.

Desde la página del manual de Linux en macros de prueba de características:

_GNU_SOURCE

La definición de esta macro (con cualquier valor) define implícitamente _ATFILE_SOURCE, _LARGEFILE64_SOURCE, _ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED, _POSIX_SOURCE, _POSIX_C_SOURCE con el valor 200809L (200112L en versiones glibc antes de glibc506 y versiones anteriores a la 2.10; 2.10) y 199 _XOPEN_SOURCE con el valor 700 (600 en versiones glibc anteriores a 2.10; 500 en versiones glibc anteriores a 2.2). Además, también se exponen varias extensiones específicas de GNU.

Desde glibc 2.19, definir _GNU_SOURCE también tiene el efecto de definir implícitamente _DEFAULT_SOURCE. En las versiones de glibc anteriores a la 2.20, definir _GNU_SOURCE también tenía el efecto de definir implícitamente _BSD_SOURCE y _SVID_SOURCE.

Nota: _GNU_SOURCE necesita ser definido antes de incluidos los archivos de encabezado para que los respectivos encabezados habiliten las funciones. Por ejemplo:

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
...

_GNU_SOURCE también se puede habilitar por compilación usando -D bandera:

$ gcc -D_GNU_SOURCE file.c

(-D no es específico de _GNU_SOURCE pero cualquier macro se define de esta manera).

Permítanme responder dos puntos más:

Algo también me molesta: ¿cómo sabe el compilador qué implementación de función vincular con el ejecutable? ¿Utiliza este #define también?

Un enfoque común es condicionalmente #define identificador basename a diferentes nombres, dependiendo de si _GNU_SOURCE se define. Por ejemplo:

#ifdef _GNU_SOURCE
# define basename __basename_gnu
#else
# define basename __basename_nongnu
#endif

Ahora la biblioteca simplemente necesita proporcionar ambos comportamientos bajo esos nombres.

Si es así, ¿por qué no dar a las personas diferentes encabezados, en lugar de tener que definir alguna variable de entorno oscura para obtener una implementación de función u otra?

A menudo, el mismo encabezado tenía contenidos ligeramente diferentes en diferentes versiones de Unix, por lo que no hay un contenido adecuado para, digamos, <string.h> – hay muchos estándares (xkcd). Hay un conjunto completo de macros para elegir su favorito, de modo que si su programa espera un estándar, la biblioteca se ajustará a eso.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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