¿Qué implica "# definir FUENTE GNU"?
Hoy tuve que usar la función basename()
, y el man 3 basename
(aquí) me dio un mensaje extraño:
Notas
Hay dos versiones diferentes de basename () - la POSIX versión descrita anteriormente, y la versión GNU , que se obtiene después de {[9]]}
#define _GNU_SOURCE
#include <string.h>
Me pregunto qué significa esto #define _GNU_SOURCE
: ¿está contaminando el código que escribo con una licencia relacionada con GNU? O es que simplemente se usa para decirle al compilador algo como " Bueno, sé que este conjunto de funciones no es POSIX, por lo tanto no es portable, pero me gustaría usarlo de todos modos".
Si es así, ¿por qué no dar a las personas diferentes encabezados, en lugar de tener que definir alguna macro oscura para obtener una implementación de función u otra?
Algo también me molesta: ¿cómo sabe el compilador qué implementación de función vincular con el ejecutable? ¿Utiliza esto #define
también?
Cualquiera tiene algunos ¿consejos para darme?
4 answers
Definir _GNU_SOURCE
no tiene nada que ver con la licencia y todo que ver con escribir código (no)portable. Si defines _GNU_SOURCE
, obtendrás:
- acceso a muchas funciones de extensión no estándar de GNU/Linux
- acceso a funciones tradicionales que fueron omitidas del estándar POSIX (a menudo por una buena razón, como ser reemplazadas por mejores alternativas, o estar vinculadas a implementaciones heredadas particulares)
- acceso a funciones de bajo nivel que no pueden ser portable, pero que a veces necesita para implementar utilidades del sistema como
mount
,ifconfig
, etc. - comportamiento roto para muchas funciones especificadas en 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 decidieron hacer lo suyo.
Mientras esté consciente 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 su los programas son portátiles.
En particular, las cosas de _GNU_SOURCE
que usted debe nunca usar son #2 y #4 arriba.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-07 15:40:09
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
está definida. 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 la gente ¿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 la misma cabecera tenía contenidos ligeramente diferentes en diferentes versiones de Unix, por lo que no hay un solo contenido correcto para, por ejemplo, <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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-12 17:51:07
Para obtener detalles exactos sobre lo que está habilitado 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 que POSIX.1 conflictos con BSD, las definiciones POSIX tienen prioridad.
De la página man de Linux en macros de prueba de características :
_GNU_SOURCE
Definir 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 anteriores a 2.10; 199506L en glibc versiones anteriores a 2.5; 199309L en glibc ver‐ sions antes de 2.1) y _XOPEN_SOURCE con el valor 700 (600 en versiones glibc antes de 2.10; 500 en versiones glibc antes 2.2). Además, varias extensiones específicas de GNU también son expuesto.
Desde glibc 2.19, la definición de _GNU_SOURCE también tiene el efecto de definiendo implícitamente _DEFAULT_SOURCE. En versiones glibc antes de la versión 2.20, la definición de _GNU_SOURCE también tenía el efecto de definiendo implícitamente _BSD_SOURCE y _SVID_SOURCE.
Nota: _GNU_SOURCE
necesita ser definido antes de incluyendo archivos de encabezado para que los encabezados respectivos habiliten las entidades. Por ejemplo:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
...
_GNU_SOURCE
también se puede habilitar por compilación usando -D
flag:
$ gcc -D_GNU_SOURCE file.c
(-D
no es específico de _GNU_SOURCE
pero cualquier macro se define de esta manera).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-16 09:17:06
De alguna lista de correo a través de google:
Mira el include/features de glibc.h:
_GNU_SOURCE Todo lo anterior, más las extensiones GNU.
Lo que significa que habilita todo esto:
STRICT_ANSI, _ISOC99_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED, _LARGEFILE_SOURCE, _LARGEFILE64_SOURCE, _FILE_OFFSET_BITS=N, _BSD_SOURCE, _SVID_SOURCE
Por lo que permite una gran cantidad de compilación banderas para gcc
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-07 13:58:51