2

I am writing a program which includes both /usr/include/linux/time.h and /usr/include/stdlib.h.

The problem is:

stdlib.h includes /usr/include/time.h, which defines 'struct timespec', and /usr/include/linux/time.h also defines one. This introduces a compilation error of redefinition.

I've examined the definitions of 'struct timespec' in these two header files:

in /usr/include/time.h:

struct timespec
{
    __time_t tv_sec;            /* Seconds.  */
    long int tv_nsec;           /* Nanoseconds.  */
};

in /usr/include/linux/time.h:

struct timespec {
    __kernel_time_t tv_sec;                 /* seconds */
    long            tv_nsec;                /* nanoseconds */
}; 

It seems that these definitions are indeed equivalent, but I can't prove it.

My question is: is there a robust way to resolve this redefinition?

Links to discussions on this problem are also highly appreciated. Thanks.

Sport
  • 8,570
  • 6
  • 46
  • 65
Patrick Pan
  • 485
  • 2
  • 6
  • 15
  • 2
    I think you wrongly include both headers: `/usr/include/linux/time.h` seems to be for kernel modules. – Liviu Dec 24 '13 at 11:36
  • 2
    Why do you want to include ``??? – alk Dec 24 '13 at 15:58
  • @Liviu thank you for your attention. My program is trying to multiplex among disk and network io's with cooperative prioriy by utilizing Linux native AIO. Sometime later when it is stable, I will release it on github. I seems that to use the AIO interface, the header file is unavoidable. How do you think? – Patrick Pan Jan 20 '14 at 03:10
  • @alk thank you for your attention. Please see my comment above. Am I right? – Patrick Pan Jan 20 '14 at 03:11
  • @Hatrick Not a Linux specialist, but I think that if you build kernel modules, then you include "/usr/include/linux/time.h", otherwise you include "/usr/include/time.h". It's not about some interface, but about including two different purpose headers. – Liviu Jan 21 '14 at 14:16

2 Answers2

5

One way to resolve the double-definition error is to rename one of these definitions:

#include <time.h>
#define timespec linux_timespec
#include <linux/time.h>
#undef timespec

And then assert at compile time that both definitions have the same layout:

typedef int assert_same_size[sizeof(struct linux_timespec) == sizeof(timespec) ? 1 : -1];
typedef int assert_same_alignment[__alignof(struct linux_timespec) == __alignof(timespec) ? 1 : -1];
typedef int assert_same_tv_sec[offsetof(struct linux_timespec, tv_sec) == offsetof(struct timespec, tv_sec) ? 1 : -1];
typedef int assert_same_tv_nsec[offsetof(struct linux_timespec, tv_nsec) == offsetof(struct timespec, tv_nsec) ? 1 : -1];
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • Great trick! Neat and powerful! Thanks Jedi Yegorushkin! May the force be with you. – Patrick Pan Jan 20 '14 at 03:12
  • How does that assert work? Is that just a way of forcing a compilation error in case the condition is false? If so, why not just use a normal assertion (i.e., via assert.h)? – Alex Quinn Dec 20 '15 at 01:47
  • 1
    @AlexQuinn It is a compile time assertion, pre C++-11 `static_assert`. http://stackoverflow.com/a/14621998/412080 – Maxim Egorushkin Dec 20 '15 at 20:11
0

I got the same error in Ecliepse Neon IDE and i resolved it by adding -DHAVE_STRUCT_TIMESPEC in C/C++ Build -> Settings -> GCC C++ Compiler -> Miscellaneous -> Others flag

enter image description here

Akash5288
  • 1,919
  • 22
  • 16