“#Define _GNU_SOURCE” ne anlama geliyor?


152

Bugün basename()işlevi kullanmak zorunda kaldım ve man 3 basename( burada ) bana garip bir mesaj verdi:

notlar

Orada iki farklı versiyonları vardır basename () - POSIX versiyonu yukarıda açıklanan ve GNU sürümü bir sonraki alır,

#define _GNU_SOURCE
#include <string.h>

Bunun ne #define _GNU_SOURCEanlama geldiğini merak ediyorum : GNU ile ilgili bir lisansla yazdığım kodu renklendiriyor mu? Veya derleyiciye " Biliyorum, bu işlevler grubu POSIX değil, bu nedenle taşınabilir değil, ama yine de kullanmak istiyorum" gibi bir şey söylemek için kullanılır .

Öyleyse, neden bir işlev uygulaması veya diğeri almak için bazı belirsiz makro tanımlamak yerine insanlara farklı başlıklar vermiyorsunuz?

Bir şey de beni rahatsız ediyor: derleyici çalıştırılabilir dosya ile bağlantı kurmak için hangi fonksiyon uygulaması biliyor? Bunu da kullanıyor mu #define?

Bana vermek için işaret eden var mı?

Yanıtlar:


172

Tanımlamanın _GNU_SOURCElisansla ilgisi yoktur ve taşınabilir kod yazmayla ilgisi yoktur. Tanımlarsanız şunları _GNU_SOURCEelde edersiniz:

  1. birçok standart dışı GNU / Linux genişletme işlevine erişim
  2. POSIX standardından çıkarılan geleneksel işlevlere erişim (genellikle daha iyi alternatiflerle değiştirilmek veya belirli eski uygulamalara bağlı olmak gibi)
  3. Bazen sistem araçları gibi uygulanması için ihtiyaç ama bu, taşınabilir olamaz düşük seviyeli işlevlerine erişim mount, ifconfigvb
  4. GNU milletinin standartlar komitesine göre fonksiyonların nasıl davranması ve kendi şeylerini yapmaya karar vermesi gerektiği konusunda pek çok POSIX tarafından belirlenmiş fonksiyon için kırık davranış.

Bunların farkında olduğunuz sürece, tanımlamak bir sorun _GNU_SOURCEolmamalı, ancak tanımlamaktan kaçınmalı ve bunun yerine programlarınızın taşınabilir olmasını sağlamak için _POSIX_C_SOURCE=200809Lveya _XOPEN_SOURCE=700mümkün olduğunda tanımlamalısınız .

Özellikle, asla kullanmamanız _GNU_SOURCEgereken şeyler yukarıdaki # 2 ve # 4'tür.


71
Tabii ki, herkes tanımlamak için gerçek sebebi _GNU_SOURCEelde etmek strfryve olduğunu bilmek memfrob.
user4815162342

5
GNU C Kütüphanesi belgelerine olan bu bağlantı bazı ek ayrıntılar sağlar (örn #define _GNU_SOURCE. "Dosyada yalnızca yorumlardan önce gelen ilk şey" olması önerilir).
Alexander Pozdneev

Alakalı değil ancak 32 bit hedeflerde 2 GB dosya boyutu sınırını genişletmek için kullanılıyor.
mckenzm

1
@mckenzm: Bence düşünüyorsun _FILE_OFFSET_BITSdeğil _GNU_SOURCE.
R .. GitHub DURDURMAK BUZ

Ben strfry memfrob ve diğer platformlar ve takım zincirlerine benzer kolaylıklar taşımak için ücretli bir programcı olmak istiyorum .
Massimo

6

İki noktayı daha yanıtlayayım:

Bir şey de beni rahatsız ediyor: derleyici çalıştırılabilir dosya ile bağlantı kurmak için hangi fonksiyon uygulaması biliyor? Bu # tanımlamayı da kullanıyor mu?

Yaygın bir yaklaşım, koşullu için #definetanımlayıcı basenamebağlı olarak, farklı isimler ile _GNU_SOURCEtanımlanır. Örneğin:

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

Şimdi kütüphanenin her iki davranışı da bu isimler altında sağlaması gerekiyor.

Öyleyse, neden bir işlev uygulaması veya diğeri almak için bazı belirsiz ortam değişkenleri tanımlamak yerine neden farklı başlıklar vermiyorsunuz?

Genellikle aynı başlık farklı Unix sürümlerinde biraz farklı içeriklere sahipti, bu yüzden <string.h>birçok standart var ( xkcd ). En sevdiğinizi seçmek için bir dizi makro vardır, böylece programınız bir standart beklerse, kütüphane buna uyacaktır.


6

Nelerin etkinleştirdiği hakkında kesin ayrıntılar için _GNU_SOURCEbelgeler yardımcı olabilir.

GNU belgelerinden:

Makro: _GNU_SOURCE

Bu makroyu tanımlarsanız, her şey dahil edilir: ISO C89, ISO C99, POSIX.1, POSIX.2, BSD, SVID, X / Açık, LFS ve GNU uzantıları. POSIX.1'in BSD ile çeliştiği durumlarda, POSIX tanımları önceliklidir.

Özellik test makrolarındaki Linux kılavuz sayfasından :

_GNU_SOURCE

Bu makronun (herhangi bir değerle) tanımlanması dolaylı olarak _ATFILE_SOURCE, _LARGEFILE64_SOURCE, _ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED, glibc sürümlerinden önce glibc sürümlerinden önce 2.1L ve 2001LL; 700 değeri olan _XOPEN_SOURCE (2,10 öncesi glibc sürümlerinde 600; 2.2 öncesi glibc sürümlerinde 500). Ek olarak, çeşitli GNU'ya özgü uzantılar da ortaya çıkar.

Glibc 2.19'dan bu yana, _GNU_SOURCE'un tanımlanması, _DEFAULT_SOURCE'un dolaylı olarak tanımlanması etkisine de sahiptir. 2.20'den önceki glibc sürümlerinde, _GNU_SOURCE'un tanımlanması, _BSD_SOURCE ve _SVID_SOURCE öğelerini dolaylı olarak tanımlama etkisine de sahipti.

Not : Üstbilgi dosyalarını eklemeden önce_GNU_SOURCE tanımlanması gerekir, böylece ilgili üstbilgiler özellikleri etkinleştirir. Örneğin:

#define _GNU_SOURCE

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

_GNU_SOURCE-Dbayrak kullanılarak derleme başına da etkinleştirilebilir :

$ gcc -D_GNU_SOURCE file.c

( -Dbelirli değildir _GNU_SOURCEancak bu şekilde herhangi bir makro tanımlanır).


4

Google üzerinden bazı posta listelerinden:

Glibc'nin include / features.h dosyasına bakın:

_GNU_SOURCE Yukarıdakilerin tümü ve GNU uzantıları.

Bu, tüm bunları mümkün kıldığı anlamına gelir:

STRICT_ANSI , _ISOC99_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED, _LARGEFILE_SOURCE, _LARGEFILE64_SOURCE, _FILE_OFFSET_BITS = N, _DOUR_SOFT_SOFT_ _

Böylece gcc için çok sayıda derleme bayrağı sağlar


21
Derleyicinin davranışını etkilemez, yalnızca başlıklardan hangi prototiplerin ve şeylerin göründüğünü etkiler.
Spudd86
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.