неявное объявление функции 'gmtime_r' - PullRequest
0 голосов
/ 29 мая 2019

Что мне нужно сделать, чтобы gcc включил объявление gmtime_r(3) из time.h?Глядя на /usr/include/time.h, gmtime_r и localtime_r внутри #ifdef __USE_POSIX.

Нужно ли что-то делать, чтобы включить __USE_POSIX, например, параметр командной строки?Я бегу с -std=c99 сейчас.Я понимаю, что макросы __USE_* не предназначены для установки непосредственно кодом пользователя.

/* Return the `struct tm' representation of *TIMER
   in Universal Coordinated Time (aka Greenwich Mean Time).  */
extern struct tm *gmtime (const time_t *__timer) __THROW;

/* Return the `struct tm' representation
   of *TIMER in the local timezone.  */
extern struct tm *localtime (const time_t *__timer) __THROW;

#ifdef __USE_POSIX
/* Return the `struct tm' representation of *TIMER in UTC,
   using *TP to store the result.  */
extern struct tm *gmtime_r (const time_t *__restrict __timer,
                struct tm *__restrict __tp) __THROW;

/* Return the `struct tm' representation of *TIMER in local time,
   using *TP to store the result.  */
extern struct tm *localtime_r (const time_t *__restrict __timer,
                   struct tm *__restrict __tp) __THROW;
#endif  /* POSIX */

Ответы [ 2 ]

5 голосов
/ 29 мая 2019

Правильный способ сделать это:

#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <time.h>

int main ()
{
    time_t t;
    struct tm tm;
    char buf[26];

    t = time (NULL);
    gmtime_r (&t, &tm);
    asctime_r (&tm, buf);
    printf ("%s", buf);

    return 0;
}

Этот метод явно указывает функции, которые требуются исходному файлу, делая его автономным. Он также переносим на любую систему POSIX, используя любой компилятор. Специальный флаг компилятора не требуется.

В GCC этот код будет компилироваться с -std = c89, -std = c99 или любым другим значением. Главное что -std = gnu ?? Включение по умолчанию может отличаться в зависимости от версии или платформы.

Подробнее см. Макросы тестирования функций .

1 голос
/ 29 мая 2019

На самом деле, gmtime_r не является частью стандарта ISO C99, это расширение POSIX.Чтобы включить это, используйте std=gnu99 стандарт.

Вы всегда можете проверить, какие функции доступны для какого стандарта в вашей системе, применив метод из этой статьи о Pixelbeat :

Иногда это может быть довольно запутаннымточно знать, что является #defined в вашей программе, и это особенно верно для макросов glibc "feature".Эти макросы документированы (info libc «макросы функциональных тестов»), но гораздо проще увидеть, что определено напрямую, с помощью «cpp -dD», например:

$ echo "#include <features.h>" | cpp -dN | grep "#define __USE_"
    #define __USE_ANSI
    #define __USE_POSIX
    #define __USE_POSIX2
    #define __USE_POSIX199309
    #define __USE_POSIX199506
    #define __USE_MISC
    #define __USE_BSD
    #define __USE_SVID

$ echo "#include <features.h>" | cpp -dN -std=c99 | grep "#define __USE_"
    #define __USE_ANSI
    #define __USE_ISOC99

Также, чтобы увидеть все предопределенные макросы, которые можно сделать:

$ cpp -dM /dev/null

Обратите внимание также на макросы, специфичные для компилятора, которые вы можете сделать:

$ gcc -E -dM - < /dev/null
...