compiler.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * compiler.h - compiler specific macros
  3. *
  4. * This file is Copyright 2010 by the GPSD project
  5. * SPDX-License-Identifier: BSD-2-clause
  6. *
  7. * Calling file needs to have previously included "gpsd_config.h"
  8. */
  9. #ifndef _GPSD_COMPILER_H_
  10. #define _GPSD_COMPILER_H_
  11. /*
  12. * Tell GCC that we want thread-safe behavior with _REENTRANT;
  13. * in particular, errno must be thread-local.
  14. * Tell POSIX-conforming implementations with _POSIX_THREAD_SAFE_FUNCTIONS.
  15. * See http://www.unix.org/whitepapers/reentrant.html
  16. */
  17. #ifndef _REENTRANT
  18. #define _REENTRANT
  19. #endif
  20. #ifndef _POSIX_THREAD_SAFE_FUNCTIONS
  21. #define _POSIX_THREAD_SAFE_FUNCTIONS
  22. #endif
  23. /* Macro for declaring function with printf-like arguments. */
  24. # if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
  25. #define PRINTF_FUNC(format_index, arg_index) \
  26. __attribute__((__format__(__printf__, format_index, arg_index)))
  27. # else
  28. #define PRINTF_FUNC(format_index, arg_indx)
  29. #endif
  30. /* Macro for declaring function arguments unused. */
  31. #if defined(__GNUC__) || defined(__clang__)
  32. #define UNUSED __attribute__((unused))
  33. #else
  34. #define UNUSED
  35. #endif
  36. // Macro to suppress FALLTHROUGH warnings
  37. #if defined(__GNUC__) && __GNUC__ >= 7
  38. #define FALLTHROUGH __attribute__((fallthrough));
  39. // At least one Clang 6 version advertises fallthrough and then chokes on it
  40. #elif defined(__clang__) && __clang_major__ > 6
  41. #ifndef __has_attribute // For backwards compatibility
  42. #define __has_attribute(x) 0
  43. #endif
  44. #if __has_attribute(fallthrough)
  45. #define FALLTHROUGH __attribute__((fallthrough));
  46. #endif
  47. #endif
  48. #ifndef FALLTHROUGH
  49. #define FALLTHROUGH
  50. #endif
  51. /*
  52. * Macro for compile-time checking if argument is an array.
  53. * It expands to constant expression with int value 0.
  54. */
  55. #if defined(__GNUC__)
  56. #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  57. 0 * (int) sizeof(({ \
  58. struct { \
  59. int unused_int; \
  60. __typeof__(arr) unused_arr; \
  61. } zero_init = {0}; \
  62. __typeof__(arr) arg_is_not_array UNUSED = { \
  63. zero_init.unused_arr[0], \
  64. }; \
  65. 1; \
  66. })) \
  67. )
  68. #else
  69. #define COMPILE_CHECK_IS_ARRAY(arr) 0
  70. #endif
  71. /* Needed because 4.x versions of GCC are really annoying */
  72. #define ignore_return(funcall) \
  73. do { \
  74. UNUSED ssize_t locresult = (funcall); \
  75. assert(locresult != -23); \
  76. } while (0)
  77. #ifdef __COVERITY__
  78. /* do nothing */
  79. #elif defined(__cplusplus)
  80. /* we are C++ */
  81. #if __cplusplus >= 201103L
  82. /* C++ before C++11 can not handle stdatomic.h or atomic */
  83. /* atomic is just C++ for stdatomic.h */
  84. #include <atomic>
  85. #endif
  86. #elif defined(HAVE_STDATOMIC_H)
  87. /* we are C and atomics are in C98 and newer */
  88. #include <stdatomic.h>
  89. #elif defined(HAVE_OSATOMIC_H)
  90. /* do it the OS X way */
  91. #include <libkern/OSAtomic.h>
  92. #endif /* HAVE_OSATOMIC_H */
  93. static inline void memory_barrier(void)
  94. /* prevent instruction reordering across any call to this function */
  95. {
  96. #ifdef __COVERITY__
  97. /* do nothing */
  98. #elif defined(__cplusplus)
  99. /* we are C++ */
  100. #if __cplusplus >= 201103L
  101. /* C++11 and later has atomics, earlier do not */
  102. std::atomic_thread_fence(std::memory_order_seq_cst);
  103. #endif
  104. #elif defined HAVE_STDATOMIC_H
  105. /* we are C and atomics are in C98 and newer */
  106. atomic_thread_fence(memory_order_seq_cst);
  107. #elif defined(HAVE_OSATOMIC_H)
  108. /* do it the OS X way */
  109. OSMemoryBarrier();
  110. #elif defined(__GNUC__)
  111. __asm__ __volatile__ ("" : : : "memory");
  112. #endif
  113. }
  114. #endif /* _GPSD_COMPILER_H_ */
  115. // vim: set expandtab shiftwidth=4