File: macros.h

package info (click to toggle)
ros2-rcutils 6.9.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,388 kB
  • sloc: ansic: 7,405; cpp: 7,369; python: 281; xml: 29; makefile: 4
file content (233 lines) | stat: -rw-r--r-- 9,036 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// Copyright 2017 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// @file

#ifndef RCUTILS__MACROS_H_
#define RCUTILS__MACROS_H_

#ifdef __cplusplus
extern "C"
{
#endif

#ifndef _MSC_VER
/// A macro to make the compiler warn when the return value of a function is not used.
#define RCUTILS_WARN_UNUSED __attribute__((warn_unused_result))
#else
/// A macro to make the compiler (MSVC) warn when the return value of a function is not used.
#define RCUTILS_WARN_UNUSED _Check_return_
#endif

/// \cond Doxygen_Suppress
// This block either sets RCUTILS_THREAD_LOCAL or RCUTILS_THREAD_LOCAL_PTHREAD.
#if defined _WIN32 || defined __CYGWIN__
// Windows or Cygwin
  #define RCUTILS_THREAD_LOCAL __declspec(thread)
#elif defined __APPLE__
// Apple OS's
  #include <TargetConditionals.h>
  #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
// iOS Simulator or iOS device
    #include <Availability.h>
    #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
      #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
// iOS >= 10, thread local storage was added in iOS 10
        #define RCUTILS_THREAD_LOCAL _Thread_local
      #else
// iOS < 10, no thread local storage, so use pthread instead
        #define RCUTILS_THREAD_LOCAL_PTHREAD 1
        #undef RCUTILS_THREAD_LOCAL
      #endif
    #else
      #error "Unknown iOS version"
    #endif
  #elif TARGET_OS_MAC
// macOS
    #define RCUTILS_THREAD_LOCAL _Thread_local
  #else
    #error "Unknown Apple platform"
  #endif
#else
// Some other non-Windows, non-cygwin, non-apple OS
  #define RCUTILS_THREAD_LOCAL _Thread_local
#endif

// Helper macros for nested macro expansion
#define RCUTILS_EXPAND(x) x
#define RCUTILS_STRINGIFY_IMPL(x) #x
#define RCUTILS_STRINGIFY(x) RCUTILS_STRINGIFY_IMPL(x)

/// A macro to mark an argument or variable as unused.
#define RCUTILS_UNUSED(x) (void)(x)

#define RCUTILS_JOIN_IMPL(arg1, arg2) arg1 ## arg2
#define RCUTILS_JOIN(arg1, arg2) RCUTILS_JOIN_IMPL(arg1, arg2)
/// @endcond

#if defined _WIN32 || defined __CYGWIN__
/// Macro to annotate printf-like functions on Linux. Disabled on Windows.
#define RCUTILS_ATTRIBUTE_PRINTF_FORMAT(format_string_index, first_to_check_index)
#else
/// Macro to annotate printf-like functions which are relying on a format string and a variable
/// number of arguments.
/**
 * This enables GCC to emit warnings if dangerous patterns are detected.
 * See GCC documentation for details:
 * https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
 *
 * For the following function:
 * ```
 * int snprintf(char *str, size_t size, const char *format, ...);
 *              ^^^^^^^^^  ^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^  ^^^
 *              ARG 1      ARG 2        ARG 3               ARG 4
 *                                      format string       first optional argument
 * ```
 * format_string_index value would be 3, first_to_check_index value would be 4.
 *
 * IMPORTANT: the first argument has an index of ONE (not zero!).
 *
 * \param[in] format_string_index index of the format string passed to the function
 * \param[in] first_to_check_index index of the first "optional argument"
 */
#define RCUTILS_ATTRIBUTE_PRINTF_FORMAT(format_string_index, first_to_check_index) \
  __attribute__ ((format(printf, format_string_index, first_to_check_index)))
#endif  // !defined _WIN32 || defined __CYGWIN__

/// Macro to declare deprecation in the platform appropriate manner.
#ifndef _WIN32
# define RCUTILS_DEPRECATED __attribute__((deprecated))
#else
# define RCUTILS_DEPRECATED __declspec(deprecated)
#endif

/// Macro to declare deprecation in the platform appropriate manner with a message.
#ifndef _WIN32
# define RCUTILS_DEPRECATED_WITH_MSG(msg) __attribute__((deprecated(msg)))
#else
# define RCUTILS_DEPRECATED_WITH_MSG(msg) __declspec(deprecated(msg))
#endif

// Provide the compiler with branch prediction information
#ifndef _WIN32
/**
 * \def RCUTILS_LIKELY
 * Instruct the compiler to optimize for the case where the argument equals 1.
 */
# define RCUTILS_LIKELY(x) __builtin_expect((x), 1)
/**
 * \def RCUTILS_UNLIKELY
 * Instruct the compiler to optimize for the case where the argument equals 0.
 */
# define RCUTILS_UNLIKELY(x) __builtin_expect((x), 0)
#else
/**
 * \def RCUTILS_LIKELY
 * No op since Windows doesn't support providing branch prediction information.
 */
# define RCUTILS_LIKELY(x) (x)
/**
 * \def RCUTILS_UNLIKELY
 * No op since Windows doesn't support providing branch prediction information.
 */
# define RCUTILS_UNLIKELY(x) (x)
#endif  // _WIN32

// Provide the compiler a hint about an argument being nonnull when possible.
#ifndef _WIN32
# define RCUTILS_NONNULL __attribute__((__nonnull__))
# define RCUTILS_NONNULL_ARGS(...) __attribute__((__nonnull__(__VA_ARGS__)))
# define RCUTILS_RETURNS_NONNULL __attribute__((__returns_nonnull__))
# define RCUTILS_HAS_NONNULL 1
#else
# define RCUTILS_NONNULL
# define RCUTILS_NONNULL_ARGS(...)
# define RCUTILS_RETURNS_NONNULL
# define RCUTILS_HAS_NONNULL 0
#endif  // _WIN32

#if defined RCUTILS_ENABLE_FAULT_INJECTION
#include "rcutils/testing/fault_injection.h"

/**
 * \def RCUTILS_CAN_RETURN_WITH_ERROR_OF
 * Indicating macro that the function intends to return possible error value.
 *
 * Put this macro as the first line in the function. For example:
 *
 * int rcutils_function_that_can_fail() {
 *   RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCUTILS_RET_INVALID_ARGUMENT);
 *   ...  // rest of function
 * }
 *
 * For now, this macro just simply calls `RCUTILS_FAULT_INJECTION_MAYBE_RETURN_ERROR` if fault
 * injection is enabled. However, for source code, the macro annotation
 * `RCUTILS_CAN_RETURN_WITH_ERROR_OF` helps clarify that a function may return a value signifying
 * an error and what those are.
 *
 * In general, you should only include a return value that originates in the function you're
 * annotating instead of one that is merely passed on from a called function already annotated with
 *`RCUTILS_CAN_RETURN_WITH_ERROR_OF`. If you are passing on return values from a called function,
 * but that function is not annotated with `RCUTILS_CAN_RETURN_WITH_ERROR_OF`, then you might
 * consider annotating that function first. If for some reason that is not desired or possible,
 * then annotate your function as if the return values you are passing on originated from your
 * function.
 *
 * If the function can return multiple return values indicating separate failure types, each one
 * should go on a separate line.
 *
 * If in your function, there are expected effects on output parameters that occur during
 * the failure case, then it will introduce a discrepancy between fault injection testing and
 * production operation. This is because the fault injection will cause the function to return
 * where this macro is used, not at the location the error values are typically returned. To help
 * protect against this scenario you may consider adding unit tests that check your function does
 * not modify output parameters when it actually returns a failing error code if it's possible for
 * your code.
 *
 * If your function is void, this macro can be used without parameters. However, for the above
 * reasoning, there should be no side effects on output parameters for all possible early returns.
 *
 * \param error_return_value the value returned as a result of an error. It does not need to be
 * a rcutils_ret_t type. It could also be NULL, -1, a string error message, etc
 */
# define RCUTILS_CAN_RETURN_WITH_ERROR_OF(error_return_value) \
  RCUTILS_FAULT_INJECTION_MAYBE_RETURN_ERROR(error_return_value);

/**
 * \def RCUTILS_CAN_FAIL_WITH
 * Indicating macro similar to RCUTILS_CAN_RETURN_WITH_ERROR_OF but for use with more complicated
 * statements.
 *
 * The `failure_code` will be executed inside a scoped if block, so any variables declared within
 * will not be available outside of the macro.
 *
 * One example where you might need this version, is if a side-effect may occur within a function.
 * For example, in snprintf, rcutils_snprintf needs to set both errno and return -1 on failure.
 * This macro is used to capture both effects.
 *
 * \param failure_code Code that is representative of the failure case in this function.
 */
# define RCUTILS_CAN_FAIL_WITH(failure_code) \
  RCUTILS_FAULT_INJECTION_MAYBE_FAIL(failure_code);

#else
# define RCUTILS_CAN_RETURN_WITH_ERROR_OF(error_return_value)
# define RCUTILS_CAN_FAIL_WITH(failure_code)
#endif  // defined RCUTILS_ENABLE_FAULT_INJECTION

#ifdef __cplusplus
}
#endif

#endif  // RCUTILS__MACROS_H_