Константы, не загруженные компилятором

Я начал изучать POSIX-таймеры, поэтому я также начал делать некоторые упражнения, но у меня сразу возникли проблемы с компилятором. При компиляции этого кода я получаю какие-то странные сообщения о макросах типа CLOCK_MONOTONIC. Они определены в различных библиотеках, таких как time.h и т. д., но компилятор выдает мне ошибки, как будто они не определены.

Это странно, потому что я использую Fedora 16, и некоторые из моих друзей с Ubuntu получают меньше ошибок компилятора, чем я :-O

Я компилирую с gcc -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -lrt

Вот ошибки, которые я получаю:

  • struct sigevent sigeventStruct дает:

    storage size of ‘sigeventStruct’ isn’t known
    unused variable ‘sigeventStruct’ [-Wunused-variable]
    Type 'sigevent' could not be resolved
    unknown type name ‘sigevent’
    
  • sigeventStruct.sigev_notify = SIGEV_SIGNAL дает:

    ‘SIGEV_SIGNAL’ undeclared (first use in this function)
    request for member ‘sigev_notify’ in something not a structure or union
    Field 'sigev_notify' could not be resolved
    
  • if(timer_create(CLOCK_MONOTONIC, sigeventStruct, numero1) == -1) дает:

    implicit declaration of function ‘timer_create’ [-Wimplicit-function- declaration]
    ‘CLOCK_MONOTONIC’ undeclared (first use in this function)
    Symbol 'CLOCK_MONOTONIC' could not be resolved
    

Вот код:

#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>

int main()
{
        timer_t numero1;
        struct sigevent sigeventStruct;
        sigeventStruct.sigev_notify = SIGEV_SIGNAL;
        if(timer_create(CLOCK_MONOTONIC, sigeventStruct, numero1) == -1)
        {
                printf( "Errore: %s\n", strerror( errno ) );
        }
        return 0;
}

person Germano Massullo    schedule 16.01.2012    source источник
comment
Просто предложение, вместо того, чтобы иметь ошибки в точечной форме, просто скопируйте их точно так, как они находятся внутри блока <pre></pre> в вопросе.   -  person Some programmer dude    schedule 16.01.2012
comment
Хорошо, в следующий раз я учту ваше предложение   -  person Germano Massullo    schedule 16.01.2012


Ответы (5)


Во-первых, вы можете скомпилировать свой код с -std=gnu99 вместо -std=c99, если хотите, чтобы были доступны идентификаторы SIGEV_SIGNAL, sigeventStruct и CLOCK_MONOTONIC.

Как отмечает @adwoodland, эти идентификаторы объявляются, когда для _POSIX_C_SOURCE установлено значение >= 199309L, как в случае с -std=gnu99. Вы также можете использовать -D_POSIX_C_SOURCE=199309L -std=c99 или определить макрос в исходном коде.

Во-вторых, см. прототип timer_create, вы должны передать указатели в качестве второго и третьего аргумента функции:

timer_create(CLOCK_MONOTONIC, &sigeventStruct, &numero1)
                              ^                ^

Также вы должны включить стандартный заголовок string.h для объявления функции strerror.

person ouah    schedule 16.01.2012
comment
Хороший улов на том, что timer_t тоже является указателем. Я пропустил это, потому что -Wall -Wextra даже не предупредил об этом! - person Flexo; 16.01.2012
comment
Я немного сбит с толку, если я компилирую с -std=gnu99, но мне нужно, чтобы #define _POSIX_C_SOURCE 199309L был записан в листинге кода? При использовании -std=c99 то же самое с использованием -D_POSIX_C_SOURCE=199309L -std=c99 или -std=c99 и #define _POSIX_C_SOURCE 199309L ? - person Germano Massullo; 16.01.2012
comment
@Caterpillar, если вы используете -std=gnu99, вам нечего делать, _POSIX_C_SOURCE будет определено автоматически, и значение будет › 199309L. С -std=c99 использование решения -D или #define эквивалентно. При использовании #define обязательно поместите #define в строку перед включением time.h и signal.h. - person ouah; 16.01.2012
comment
Я решил много проблем, но CLOCK_MONOTONIC все еще не может быть решен. Я использую -std=gnu99 - person Germano Massullo; 17.01.2012

Если вы используете -std=c99, вам нужно сообщить gcc, что вы все еще используете последние версии POSIX:

#define _POSIX_C_SOURCE 199309L

перед любым #include или даже с -D в командной строке.

Другие ошибки:

  • Отсутствует #include <string.h>
  • Вам нужен указатель на timer_create, т.е. &sigeventStruct вместо просто sigeventStruct
person Flexo    schedule 16.01.2012

Другие ответы предлагают _POSIX_C_SOURCE в качестве разрешающего макроса. Это, безусловно, работает, но не обязательно включает все, что есть в Единой спецификации Unix (SUS). Для этого необходимо установить _XOPEN_SOURCE, что также автоматически устанавливает _POSIX_C_SOURCE . У меня есть заголовок, который я называю "posixver.h", который содержит:

/*
** Include this file before including system headers.  By default, with
** C99 support from the compiler, it requests POSIX 2001 support.  With
** C89 support only, it requests POSIX 1997 support.  Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/

/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */

#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600   /* SUS v3, POSIX 1003.1 2004 (POSIX 2001 + Corrigenda) */
#else
#define _XOPEN_SOURCE 500   /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */

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

person Jonathan Leffler    schedule 16.01.2012
comment
Спасибо, я храню эту библиотеку для дальнейших целей - person Germano Massullo; 16.01.2012

Ссылаясь на проблему CLOCK_MONOTONIC, которая не определена:

Как указала Caterpillar, это ошибка eclipse, точнее ошибка CDT-Indexer с обходным путем по адресу ошибки затмения, комментарий 12

person xmoex    schedule 02.05.2012
comment
Вы должны добавить обходной путь в случае, если ссылка умирает - person OMGtechy; 12.02.2016

Я решил много проблем с -std=gnu99 (без указания версий POSIX), но у меня все еще есть

CLOCK_MONOTONIC could not be resolved

Поискав в Интернете, я нашел несколько отчетов об ошибках Eclipse, в которых люди жалуются на это. Нужно лучше проверить, если это ошибка Eclipse, потому что с

gcc -Wall -w -o Blala timer.c -std=gnu99 -lrt

он компилирует

person Germano Massullo    schedule 17.01.2012
comment
Да, это ошибка плагина Eclipse CDT. - person Germano Massullo; 17.01.2012