Как я получаю 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 один вместо этого.
Из заголовка ] 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 ()
.