Как получить POSIX strerror_r вместо версии GNU?

Как я получаю POSIX strerror_r вместо версии GNU?

Я компилирую с g ++ на Ubuntu 8.04 с glibc версией 2.7 (на основе того, что находится в).

Править

На вышеупомянутой странице справочника это говорит:

Тестовые Требования Макроса функции для glibc (см. feature_test_macros (7)):

   The XSI-compliant version of strerror_r() is provided if:
   (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
   Otherwise, the GNU-specific version is provided.

Это затем говорит в feature_test_macros (7):

   If no feature test macros are explicitly defined, then the following feature
   test macros are defined by default: _BSD_SOURCE, _SVID_SOURCE, _POSIX_SOURCE,
   and _POSIX_C_SOURCE=200809L (200112L in glibc versions before 2.10; 199506L in
   glibc versions before 2.4; 199309L in glibc versions before 2.1).

Таким образом, я должен получать версию POSIX, но я получаю GNU один вместо этого.

10
задан Robert S. Barnes 16 June 2010 в 11:20
поделиться

1 ответ

Из заголовка ] string.h :

/* Reentrant version of `strerror'.
   There are 2 flavors of `strerror_r', GNU which returns the string
   and may or may not use the supplied temporary buffer and POSIX one
   which fills the string into the buffer.
   To use the POSIX version, -D_XOPEN_SOURCE=600 or -D_POSIX_C_SOURCE=200112L
   without -D_GNU_SOURCE is needed, otherwise the GNU version is
   preferred.  */

Обратите внимание, будьте осторожны при использовании расширений GNU, включайте их ( _GNU_SOURCE ) в последнюю очередь, прежде чем включать заголовки, на которые вы хотите повлиять (или отменить определение стратегически) . Однако не стоит беспокоиться, если вы не используете расширения GNU.

Обычно, если GNU отклоняется от POSIX в поведении по умолчанию, вы увидите некоторые комментарии в заголовке, чтобы указать, как вы можете получить поведение POSIX. Это также (обычно) задокументировано в руководстве по glibc, но не всегда попадает в сжатые справочные страницы.

Правка

Попробуйте этот простой тест:

#include <string.h>
#ifdef _GNU_SOURCE
#error "Something turned it on!"
#endif

Или, точнее,

#ifdef _GNU_SOURCE
#undef _GNU_SOURCE
#endif
#include <string.h>

Если _POSIX_C_SOURCE = {version} определено, вы должны иметь версию POSIX, если что-то в противном случае предпочтение было отдано версии GNU.

Единственное, что я могу придумать, это _GNU_SOURCE . Я уверен, что этого нет в ваших флагах командной строки, вы бы это видели. Возможно, его включила другая включенная библиотека.

Это то, что я имел в виду, говоря о том, что расширения «хитрые», когда просили отдать предпочтение реализациям POSIX, даже если вы их не включаете.

Изменить

Если что-то включается _GNU_SOURCE (я не могу вспомнить, работает ли boost или нет, я не использую C ++ почти так же часто, как C), вы, вероятно, захотите позвольте ему это сделать. Вы можете использовать - undef "[макрос]" -U [макрос] из командной строки. Однако это не сработает, если код библиотеки выглядит следующим образом:

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <stdio.h>
#include <string.h>

#ifdef _GNU_SOURCE
#error "It didn't work"
#endif

int main(void)
{
   return 0;
}

Проблема в том, что к тому времени, когда ваш код действительно включает string.h , что-то еще уже включило расширения и включило его. Включите охранников, естественно, чтобы вы не включили его дважды.

Попробуйте явно отключить _GNU_SOURCE и включить string.h до чего-либо остального. Это предотвращает включение этих расширений другими библиотеками. Однако эти библиотеки могут не работать без них. Некоторый код просто «ожидает» поведения GNU и не включает откат к POSIX.

Я испытал подобное разочарование из-за кода библиотеки, который не работает без asprintf () .

7
ответ дан 4 December 2019 в 00:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: