Constants not loaded by compiler

14.5k views Asked by At

I started studying POSIX timers, so I started also doing some exercises, but I immediately had some problems with the compiler. When compiling this code, I get some strange messages about macros like CLOCK_MONOTONIC. Those are defined in various libraries like time.h etc. but the compiler gives me errors as if they are not defined.

It is strange because I am using a Fedora 16, and some of my friends with Ubuntu get less compiler errors than I :-O

I am compiling with gcc -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -lrt

Here the errors I get:

  • struct sigevent sigeventStruct gives:

    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 gives:

    ‘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) gives:

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

Here is the code:

#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;
}
5

There are 5 answers

4
ouah On BEST ANSWER

Firstly, you can compile your code with -std=gnu99 instead of -std=c99 if you want to have the identifiers SIGEV_SIGNAL, sigeventStruct, and CLOCK_MONOTONIC available.

As noted by @adwoodland these identifiers are declared when _POSIX_C_SOURCE is set to a value >= 199309L, which is the case with -std=gnu99. You can also use -D_POSIX_C_SOURCE=199309L -std=c99 or have the macro defined in source code.

Secondly, see the timer_create prototype, you have to pass pointers as the second and the third argument to the function:

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

Also you have to include the standard header string.h for strerror function declaration.

0
Flexo On

If you are using -std=c99 you need to tell gcc you're still using recent versions of POSIX:

#define _POSIX_C_SOURCE 199309L

before any #include, or even with -D on the command line.

Other errors:

  • Missing #include <string.h>
  • You need a pointer for timer_create, i.e. &sigeventStruct instead of just sigeventStruct
1
Jonathan Leffler On

The other answers suggest _POSIX_C_SOURCE as the enabling macro. That certainly works, but it doesn't necessarily enable everything that is in the Single Unix Specification (SUS). For that, you should set _XOPEN_SOURCE, which also automatically sets _POSIX_C_SOURCE. I have a header I call "posixver.h" which contains:

/*
** 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 */

It is tuned for the systems I work with which don't all recognize the 700 value. If you are working on a relatively modern Linux, I believe you can use 700. It's in a header so that I only have to change one file when I want to alter the rules.

1
Germano Massullo On

I solved a lot of problems with -std=gnu99 (without specifing any POSIX versions) but I am still having

CLOCK_MONOTONIC could not be resolved

Searching on internet I found some Eclipse bugreports with people complaining about this. Have to check better if is an Eclipse bug, because with

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

it compiles

1
xmoex On

Referring to the CLOCK_MONOTONIC not being defined problem:

As Caterpillar pointed out this is an eclipse bug, more precisely a CDT-Indexer bug with a workaround at eclipse bugs, comment 12