tags:

views:

124

answers:

2

When I try to compile this on Linux with -std=c99 gcc complains about not knowing struct timespec. However if I compile this w/o -std=c99 everything works fine.

#include <time.h>

void blah(struct timespec asdf)
{}

int main()
{
  struct timespec asdf;
  return 0;
}

Why is this and is there a way to still get it to work with -std=c99?

+2  A: 

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
sharth
Not really an answer to the question
dark_charlie
He's comparing -std=gnu89 to -std=c99. The more correct comparison would be -std=gnu89 to -std=gnu99. Although I do agree that Jonathan's answer explains what is going on here much better.
sharth
The downvotes on this answer are completely unwarranted. It makes it clear that the OP is comparing `gnu89` with `c99`, which is why the error arises, and shows that the same error arises with `c89`. It is useful supplemental information.
caf
+9  A: 

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

For my systems, POSIX 2008 is not as widely available as 2004, so that's what I use - but YMMV. Note that SUS v3 and v4 both require C99 compilation. On Solaris, at least, using C89 will fail.

Jonathan Leffler
You should define `_POSIX_C_SOURCE` to the proper values if you just want POSIX. `_XOPEN_SOURCE` is for XSI extensions.
R..
@R..: Yes, you are pedantically correct. However, in practice, do you really want only POSIX and not XSI? If so, you can read up and set just POSIX. For most people, most of the time, the solution given is sensible.
Jonathan Leffler
In the latest SUS, pretty much all worthwhile functionality has been moved to base, and XSI is mostly legacy interface cruft. Of course I'm covering my back by saying "mostly". ;-)
R..