When I try to compile this on Linux with gcc -std=c99, the compiler complains about not knowing struct timespec. However if I compile this without -std=c99 everything works fine.
#include <time.h>
int main(void)
{
struct timespec asdf;
return 0;
}
Why is this and is there a way to still get it to work with -std=c99?
Explicitly enabling POSIX features
The timespec comes from POSIX, so you have to 'enable' POSIX definitions:
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 500
#endif /* __STDC_VERSION__ */
#include <time.h>
void blah(struct timespec asdf)
{
}
int main()
{
struct timespec asdf;
return 0;
}
The stanza at the top is what I currently use - it triggers the definitions from Single UNIX Specification (SUS) based on whether you're using a C99 or C89 compiler.
If you want the POSIX 2008 (SUS v4) material, use _XOPEN_SOURCE 700
If you want the POSIX 2004 (SUS v3) material, use _XOPEN_SOURCE 600
If you want the POSIX 1995 (SUS v2, 1997) material, use _XOPEN_SOURCE 500
As noted in the comments, using _XOPEN_SOURCE strictly enables the XSI (X/Open System Interface) extensions over strict POSIX, but it is very rare for you to want POSIX and not XSI. You should normally specify _XOPEN_SOURCE and not futz with _POSIX_C_SOURCE. See (POSIX 2018) on The Compilation Environment for more information about feature macros.
For my systems in 2010, POSIX 2008 was not as widely available as POSIX 2004, so that's what I used - but YMMV. Note that SUS v3 and v4 both require C99 compilation. On Solaris, at least, using C89 failed.
GCC provides -std=gnuXX options
If you specify -std=c11 to GCC (or Clang emulating GCC), then only the standard C definitions are enabled. If you use -std=gnu11, then POSIX and other extensions to standard C are visible by default.
Note that GCC 4.x and earlier used -std=gnu90 (corresponding to C90 plus extensions) by default. GCC 5.x and later use -std=gnu11 by default. There was never a version of GCC that enabled -std=gnu99 by default.
Use a header to control the POSIX version information
I now (2019) use a header to encapsulate this information so that future changes only require the change to a single header, not to every source file that uses POSIX features. It was painful editing the old stanza out of multiple source files as time passed and POSIX 2008 became prevalent.
/*
#(#)File: $RCSfile: posixver.h,v $
#(#)Version: $Revision: 1.4 $
#(#)Last changed: $Date: 2017/06/18 00:15:42 $
#(#)Purpose: Request appropriate POSIX and X/Open Support
#(#)Author: J Leffler
#(#)Copyright: (C) JLSS 2010-2017
*/
/*TABSTOP=4*/
#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_POSIXVER_H
/*
** Include this file before including system headers. By default, with
** C99 support from the compiler, it requests POSIX 2008 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 defined(__cplusplus)
#define _XOPEN_SOURCE 700 /* SUS v4, POSIX 1003.1 2008/13 (POSIX 2008/13) */
#elif __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 700 /* SUS v4, POSIX 1003.1 2008/13 (POSIX 2008/13) */
#else
#define _XOPEN_SOURCE 500 /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
#endif /* JLSS_ID_POSIXVER_H */
You may use the information from this header without the attribution and copyright notice normally required by the "CC by-sa 3.0" licence used by Stack Overflow. This code is available in my SOQ (Stack Overflow Questions) repository on GitHub as file posixver.h in the src/libsoq sub-directory.
C11 defines struct timespec
Note that C11 defines struct timespec, and does so in a way that is compatible with POSIX (which defined it first).
The header <time.h> defines the type. Three of the functions that use it are declared in <threads.h> and the other is in <time.h>:
cnd_timedwait()
mtx_timedlock()
thrd_sleep()
timespec_get()
These are also part of C17 (C18) of course. You would have to be compiling with -std=c11 or similar (GCC 9.2.0 seems to recognize both -std=c17 and -std=c18, and -std=c2x for the next version of the standard) for the type struct timespec to be defined automatically.
I would recommend compiling with -std=gnu99.
To elaborate on this. By default, gcc compiles with -std=gnu89. Here are the results for the following source code.
#include <time.h>
int main() {
struct timespec asdf;
return 0;
}
[1:25pm][wlynch#cardiff /tmp] gcc -std=gnu89 foo.c
[1:26pm][wlynch#cardiff /tmp] gcc -std=gnu99 foo.c
[1:25pm][wlynch#cardiff /tmp] gcc -std=c89 foo.c
foo.c: In function ‘main’:
foo.c:4: error: storage size of ‘asdf’ isn’t known
[1:26pm][wlynch#cardiff /tmp] gcc -std=c99 foo.c
foo.c: In function ‘main’:
foo.c:4: error: storage size of ‘asdf’ isn’t known
Adding -D_GNU_SOURCE to your CFLAGS will also work.
gcc test.c -o test -std=c99 -D_GNU_SOURCE
Have a look at /usr/include/time.h. This is the preprocessor conditional that wraps the timespec definition. _GNU_SOURCE enables __USE_POSIX199309.
#if (!defined __timespec_defined \
&& ((defined _TIME_H \
&& (defined __USE_POSIX199309 \
|| defined __USE_ISOC11)) \
|| defined __need_timespec))
# define __timespec_defined 1
struct timespec
{
__time_t tv_sec; /* Seconds. */
__syscall_slong_t tv_nsec; /* Nanoseconds. */
};
The <stdarg.h> header file is used to make functions accept undefined number of arguments, right?
So, the printf() funtion of <stdio.h> must be using <stdarg.h> to accept avariable number of arguments(please correct me if I'm mistaken).
I found the following lines in the stdio.h file of gcc:
#if defined __USE_XOPEN || defined __USE_XOPEN2K8
# ifdef __GNUC__
# ifndef _VA_LIST_DEFINED
typedef _G_va_list va_list;
# define _VA_LIST_DEFINED
# endif
# else
# include <stdarg.h>//////////////////////stdarg.h IS INCLUDED!///////////
# endif
#endif
I can't understand most of what's in it, but it appears to be including <stdarg.h>
So, if printf() uses <stdarg.h> for accepting variable number of arguments and stdio.h has printf(), a C program using printf() need not include <stdarg.h> does it?
I tried a program which had printf() and a user-defined function accepting variable number of arguments.
The program I tried is:
#include<stdio.h>
//#include<stdarg.h>///If this is included, the program works fine.
void fn(int num, ...)
{
va_list vlist;
va_start(vlist, num);//initialising va_start (predefined)
int i;
for(i=0; i<num; ++i)
{
printf("%d\n", va_arg(vlist, int));
}
va_end(vlist);//clean up memory
}
int main()
{
fn(3, 18, 11, 12);
printf("\n");
fn(6, 18, 11, 32, 46, 01, 12);
return 0;
}
It works fine if <stdarg.h> is included but otherwise generates the following error:
40484293.c:13:38: error: expected expression before ‘int’
printf("%d\n", va_arg(vlist, int));//////error: expected expression before 'int'/////////
^~~
How is this?
Or is it that printf() doesn't use <stdarg.h> for accepting variable number of arguments?
If so, how is it done?
Consider:
stdio.h:
int my_printf(const char *s, ...);
Do you need <stdarg.h>? No, you don't. ... is part of the grammar of the language - it's "built-in". However, as soon as you want to do anything meaningful and portable with such list of arguments, you need the names defined in there: va_list, va_start and so on.
stdio.c:
#include "stdio.h"
#include "stdarg.h"
int my_printf(const char *s, ...)
{
va_list va;
va_start(va, s);
/* and so on */
}
But this will be necessary, essentially, in the implementation of your libc which is something you don't see unless you compile the library on your own. What you instead get is the libc shared library, which has already been compiled to machine code.
So, if printf() uses for accepting variable number of
arguments and stdio.h has printf(), a C program using printf() need
not include does it?
Even if it were so, you cannot rely on that, otherwise your code is ill-formed: you must include all the headers anyway if a name belonging to them is used, regardless whether the implementation already does that or not.
I'm first going to answer your question in terms of the C standard, because that is what tells you how you should write your code.
The C standard requires stdio.h to "behave as-if" it does not include stdarg.h. In other words, the macros va_start, va_arg, va_end, and va_copy, and the type va_list, are required not to be made available by including stdio.h. In other other words, this program is required not to compile:
#include <stdio.h>
unsigned sum(unsigned n, ...)
{
unsigned total = 0;
va_list ap;
va_start(ap, n);
while (n--) total += va_arg(ap, unsigned);
va_end(ap);
return total;
}
(This is a difference from C++. In C++, all standard library headers are allowed, but not required, to include each other.)
It is true that the implementation of printf (probably) uses the stdarg.h mechanism to access its arguments, but that just means that some files in the source code for the C library ("printf.c", perhaps) need to include stdarg.h as well as stdio.h; that doesn't affect your code.
It is also true that stdio.h declares functions that take va_list-typed arguments. If you look at those declarations, you will see that they actually use a typedef name that begins with either two underscores, or an underscore and a capital letter: for instance, with the same stdio.h you are looking at,
$ egrep '\<v(printf|scanf) *\(' /usr/include/stdio.h
extern int vprintf (const char *__restrict __format, _G_va_list __arg);
extern int vscanf (const char *__restrict __format, _G_va_list __arg);
All names that begin with two underscores, or an underscore and a capital letter, are reserved for the implementation - stdio.h is allowed to declare as many such names as it wants. Conversely, you, the application programmer, are not allowed to declare any such names, or use the ones that the implementation declares (except the subset that are documented, such as _POSIX_C_SOURCE and __GNUC__). The compiler will let you do it, but the effects are undefined.
Now I'm going to talk about the thing you quoted from stdio.h. Here it is again:
#if defined __USE_XOPEN || defined __USE_XOPEN2K8
# ifdef __GNUC__
# ifndef _VA_LIST_DEFINED
typedef _G_va_list va_list;
# define _VA_LIST_DEFINED
# endif
# else
# include <stdarg.h>
# endif
#endif
To understand what this is doing, you need to know three things:
Recent "issues" of POSIX.1, the official specification of what it means to be a "Unix" operating system, add va_list to the set of things stdio.h is supposed to define. (Specifically, in Issue 6, va_list is defined by stdio.h as an "XSI" extension, and in Issue 7 it's mandatory.) This code defines va_list, but only if the program has requested Issue 6+XSI or Issue 7 features; that's what #if defined __USE_XOPEN || defined __USE_XOPEN2K8 means. Notice that it is using _G_va_list to define va_list, just as, elsewhere, it used _G_va_list to declare vprintf. _G_va_list is already available somehow.
You cannot write the same typedef twice in the same translation unit. If stdio.h defined va_list without somehow notifying stdarg.h not to do it again,
#include <stdio.h>
#include <stdarg.h>
would not compile.
GCC comes with a copy of stdarg.h, but it does not come with a copy of stdio.h. The stdio.h you are quoting comes from GNU libc, which is a separate project under the GNU umbrella, maintained by a separate (but overlapping) group of people. Crucially, GNU libc's headers cannot assume that they are being compiled by GCC.
So, the code you quoted defines va_list. If __GNUC__ is defined, which means the compiler is either GCC or a quirk-compatible clone, it assumes that it can communicate with stdarg.h using a macro named _VA_LIST_DEFINED, which is defined if and only if va_list is defined — but being a macro, you can check for it with #if. stdio.h can define va_list itself and then define _VA_LIST_DEFINED, and then stdarg.h won't do it, and
#include <stdio.h>
#include <stdarg.h>
will compile fine. (If you look at GCC's stdarg.h, which is probably hiding in /usr/lib/gcc/something/something/include on your system, you will see the mirror image of this code, along with a hilariously long list of other macros that also mean "don't define va_list, I already did that" for other C libraries that GCC can, or could once, be used with.)
But if __GNUC__ is not defined, then stdio.h assumes it does not know how to communicate with stdarg.h. But it does know that it's safe to include stdarg.h twice in the same file, because the C standard requires that to work. So in order to get va_list defined, it just goes ahead and includes stdarg.h, and thus, the va_* macros that stdio.h isn't supposed to define will also be defined.
This is what the HTML5 people would call a "willful violation" of the C standard: it's wrong, on purpose, because being wrong in this way is less likely to break real-world code than any available alternative. In particular,
#include <stdio.h>
#include <stdarg.h>
is overwhelmingly more likely to appear in real code than
#include <stdio.h>
#define va_start(x, y) /* something unrelated to variadic functions */
so it's much more important to make the first one work than the second, even though both are supposed to work.
Finally, you might still be wondering where the heck _G_va_list came from. It's not defined anywhere in stdio.h itself, so it must either be a compiler intrinsic, or be defined by one of the headers stdio.h includes. Here's how you find out everything that a system header includes:
$ echo '#include <stdio.h>' | gcc -H -xc -std=c11 -fsyntax-only - 2>&1 | grep '^\.'
. /usr/include/stdio.h
.. /usr/include/features.h
... /usr/include/x86_64-linux-gnu/sys/cdefs.h
.... /usr/include/x86_64-linux-gnu/bits/wordsize.h
... /usr/include/x86_64-linux-gnu/gnu/stubs.h
.... /usr/include/x86_64-linux-gnu/gnu/stubs-64.h
.. /usr/lib/gcc/x86_64-linux-gnu/6/include/stddef.h
.. /usr/include/x86_64-linux-gnu/bits/types.h
... /usr/include/x86_64-linux-gnu/bits/wordsize.h
... /usr/include/x86_64-linux-gnu/bits/typesizes.h
.. /usr/include/libio.h
... /usr/include/_G_config.h
.... /usr/lib/gcc/x86_64-linux-gnu/6/include/stddef.h
.... /usr/include/wchar.h
... /usr/lib/gcc/x86_64-linux-gnu/6/include/stdarg.h
.. /usr/include/x86_64-linux-gnu/bits/stdio_lim.h
.. /usr/include/x86_64-linux-gnu/bits/sys_errlist.h
I used -std=c11 to make sure I was not compiling in POSIX Issue 6+XSI nor Issue 7 modes, and yet we see stdarg.h in this list anyway — not included directly by stdio.h, but by libio.h, which is not a standard header. Let's have a look in there:
#include <_G_config.h>
/* ALL of these should be defined in _G_config.h */
/* ... */
#define _IO_va_list _G_va_list
/* This define avoids name pollution if we're using GNU stdarg.h */
#define __need___va_list
#include <stdarg.h>
#ifdef __GNUC_VA_LIST
# undef _IO_va_list
# define _IO_va_list __gnuc_va_list
#endif /* __GNUC_VA_LIST */
So libio.h includes stdarg.h in a special mode (here's another case where implementation macros are used to communicate between system headers), and expects it to define __gnuc_va_list, but it uses it to define _IO_va_list, not _G_va_list. _G_va_list is defined by _G_config.h...
/* These library features are always available in the GNU C library. */
#define _G_va_list __gnuc_va_list
... in terms of __gnuc_va_list. That name is defined by stdarg.h:
/* Define __gnuc_va_list. */
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
typedef __builtin_va_list __gnuc_va_list;
#endif
And __builtin_va_list, finally, is an undocumented GCC intrinsic, meaning "whatever type is appropriate for va_list with the current ABI".
$ echo 'void foo(__builtin_va_list x) {}' |
gcc -xc -std=c11 -fsyntax-only -; echo $?
0
(Yes, GNU libc's implementation of stdio is way more complicated than it has any excuse for being. The explanation is that back in elder days people tried to make its FILE object directly usable as a C++ filebuf. That hasn't worked in decades — in fact, I'm not sure if it ever worked; it had been abandoned before EGCS, which is as far back as I know the history — but there are many, many vestiges of the attempt hanging around still, either for binary backward compatibility or because nobody has gotten around to cleaning them up.)
(Yes, if I'm reading this correctly, GNU libc's stdio.h won't work right with a C compiler whose stdarg.h doesn't define __gnuc_va_list. This is abstractly wrong, but harmless; anyone wanting a shiny new non-GCC-compatible compiler to work with GNU libc is going to have a whole lot more things to worry about.)
stdarg header file is used to make functions accept undefined number
of arguments, right?
No, <stdarg.h> just exposes an API that should be used to access extra arguments. There is no necessity to include that header if you want just declare function that accepts variable number of arguments, like this:
int foo(int a, ...);
This is a language feature and requires no extra declarations / definitions.
I found the following lines in the stdio.h file of gcc:
#if defined __USE_XOPEN || defined __USE_XOPEN2K8
# ifdef __GNUC__
# ifndef _VA_LIST_DEFINED
typedef _G_va_list va_list;
# define _VA_LIST_DEFINED
# endif
# else
# include <stdarg.h>//////////////////////stdarg.h IS INCLUDED!///////////
# endif
#endif
I guess this stuff is required only to declare things like vprintf() without internal including of <stdarg.h>:
int vprintf(const char *format, va_list ap);
To top it off:
Header that declares function with variable number of arguments shouldn't include <stdarg.h> internally.
Implementation of function with variable number of arguments must include <stdarg.h> and use va_list API to access extra arguments.
No, to use printf() all you need is #include <stdio.h>. There's no need for stdarg because printf is already compiled. The compiler only needs to see a prototype for printf to know that it is variadic (derived from the ellipsis ... in the prototype). If you look at the stdio library source code for printf you'll see the <stdarg.h> being included.
If you want to write your own variadic function, you must #include <stdarg.h> and use its macros accordingly. As you can see, if you forget to do that, the va_start/list/end symbols are unknown to the compiler.
If you want to see a real implementation of printf, look at the code in FreeBSD's standard I/O source, along with the source for vfprintf.
Fundamentals of splitting a module into a header file and a source file:
In the header file, you put only the interface of your module
In the source file, you put the implementation of your module
So even if the implementation of printf makes use of va_arg as you speculate:
In stdio.h, the author only declared int printf(const char* format, ...);
In stdio.c, the author implemented printf using va_arg
This implementation of stdio.h does not include stdarg.h when compiled with gcc. It works by magic that compiler writers always have up their sleeves.
Your C source files must include every system header they reference anyway. It is a requirement of the C standard. That is, if your source code requires definitions present in stdarg.h, it must contain #include <stdarg.h> directive either directly, or in one of your header files that it includes. It cannot rely on stdarg.h being included in other standard headers, even if they do in fact include it.
The <stdarg.h> file is required to be included only if you are going to implement a variable number of arguments function. It's not required to be able to use printf(3) and friends. Only if you are going to process arguments on a variable number of args function, you'll need the va_list type, and the va_start, va_arg and va_end macros. So, only then you'll need to forcibly include that file.
In general, you are not warranted that <stdarg.h> will be included with just including <stdio.h> Indeed, the code you cite only includes it, if __GNU_C__ is not defined (which I suspect, is the case, so it's not included in your case) and this macro is defined if you are using the gcc compiler.
If you are going to create variable argument passing functions in your code, the best approach is not to expect another included file to include it, but do it yourself (as a client for the requested functionality you are) everywhere you are using the va_list type, or va_start, va_arg or va_end macros.
In the past, there was some confusion about double inclusion, as some header files were not protected from double inclusion (including twice or more times the same include file produced errors about doubly defined macros or similar and you had to go with care) but today, this is not an issue and normally all standard header fields are protected from double inclusion.
Okay, there is the "regular" printf family: printf, fprintf, dprintf, sprintf, and snprintf.
And then there's the variable number of arguments printf family: vprintf, vfprintf, vdprintf, vsprintf, and vsnprintf.
To use a variable list of arguments with either, you need to declare stdarg.h.
stdarg.h defines all the macros you're using: va_list, va_start, va_arg, va_end, and va_copy.
I am trying to use the posix function isatty() in my C code, to tell if the output is being redirected. However, to do this I need a file descriptor, and from my research it looks like fileno() is no longer included with stdio.h. Are there any alternative methods of getting a file descriptor?
It's still there, but you may have to explicitly turn on POSIX features. In particular, under Linux, fileno is only available if POSIX or XOPEN features are enabled. From the fileno(3) manpage:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
fileno(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
So, compile with -D_POSIX_SOURCE.
If you just want to know if output is being redirected, you can use:
#include <unistd.h>
...
if (isatty(STDOUT_FILENO))
error("redirect output.");
STDOUT_FILENO is generally 1.
fileno() is still the POSIX-standard way of getting the file descriptor associated with a file stream.
What compilation options are you using, on which platform(s)? Are you enabling the POSIX extensions?
gcc -std=gnu99 ...
This should make fileno() visible. (Using gcc -std=c99 -pedantic may make them invisible.)
Alternatively, add a variation on this stanza to your code, or put it in a header and include that at the start of your code:
#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_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 */
#endif /* JLSS_ID_POSIXVER_H */
For my purposes, _XOPEN_SOURCE set to 600 is better than 700; it works out of the box on more machine types. You may be able to use 700. I keep this in a file posixver.h and my code starts
#include "posixver.h"
before any of the system headers. This allows me to change the rules (600 to 700, for example) centrally and I only need to recompile, not edit every source file.
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;
}
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.
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
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.
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
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