TR_datastructures 0.1.0
A generic C data structures library
Loading...
Searching...
No Matches
tr_export.h
Go to the documentation of this file.
1/**
2 * @file tr_export.h
3 * @brief Symbol visibility and compiler annotation macros
4 *
5 * Provides macros for controlling symbol visibility across platforms
6 * and build types. Supports MSVC, GCC, Clang and unknown compilers
7 * with graceful degradation.
8 *
9 * The following macros are defined:
10 * - @ref TR_API — marks a public API symbol
11 * - @ref TR_INTERNAL — marks an internal symbol
12 * - @ref TR_DEPRECATED — marks a deprecated symbol
13 * - @ref TR_NODISCARD — warns if return value is ignored
14 */
15/*******************************************************************************************************
16 * NAME: tr_export.h
17 *
18 * PURPOSE: Defines macros for controlling symbol visibility across platforms and build types
19 *
20 * GLOBAL VARIABLES: None
21 *
22 * DEVELOPMENT HISTORY:
23 *
24 * Date Author Change Id Release Description Of Change
25 * ---------- --------------- --------- ------- -----------------------------------
26 * 24-05-2026 Tiago Rodrigues 1 File preparation
27 *
28 *******************************************************************************************************/
29#ifndef TR_EXPORT_H
30#define TR_EXPORT_H
31
32/* 0 copyright/licensing */
33/*******************************************************************************************************
34 *
35 * This is free and unencumbered software released into the public domain (Unlicense).
36 *
37 ********************************************************************************************************/
38
39#ifdef __cplusplus
40extern "C"
41{
42#endif
43
44/* 1 includes */
45/*****************************************************/
46/*****************************************************/
47
48/* 2 defines */
49/*****************************************************/
50
51/* ------------------------------------------------------------------
52 * 2.1 Compiler visibility support detection
53 * ------------------------------------------------------------------ */
54/**
55 * @defgroup tr_export_visibility Compiler Detection Macros
56 * @{
57 *
58 * @brief Internal macros for raw compiler visibility attributes
59 *
60 * These are internal building blocks for @ref TR_API and @ref TR_INTERNAL.
61 * Do not use these directly in consuming code — use @ref TR_API instead.
62 *
63 * | Macro | MSVC | GCC/Clang | Unknown |
64 * |--------------------|-------------------------|------------------------------------|---------|
65 * | TR_EXPORT_SYMBOL | __declspec(dllexport) | __attribute__((visibility("default"))) | (empty)
66 * | | TR_IMPORT_SYMBOL | __declspec(dllimport) | __attribute__((visibility("default"))) |
67 * (empty) | | TR_LOCAL_SYMBOL | (not supported) | __attribute__((visibility("hidden")))
68 * | (empty) |
69 */
70#if defined(_MSC_VER)
71/* Microsoft Visual C++ compiler */
72#define TR_EXPORT_SYMBOL __declspec(dllexport)
73#define TR_IMPORT_SYMBOL __declspec(dllimport)
74#define TR_LOCAL_SYMBOL /* not supported on MSVC */
75
76#elif defined(__GNUC__) && (__GNUC__ >= 4)
77/* GCC version 4 or later - visibility attributes supported */
78#define TR_EXPORT_SYMBOL __attribute__((visibility("default")))
79#define TR_IMPORT_SYMBOL __attribute__((visibility("default")))
80#define TR_LOCAL_SYMBOL __attribute__((visibility("hidden")))
81
82#elif defined(__clang__)
83/* Clang - visibility attributes supported */
84#define TR_EXPORT_SYMBOL __attribute__((visibility("default")))
85#define TR_IMPORT_SYMBOL __attribute__((visibility("default")))
86#define TR_LOCAL_SYMBOL __attribute__((visibility("hidden")))
87
88#else
89/* unknown compiler / GCC less than 4 - no visibility support, degrade gracefully */
90#define TR_EXPORT_SYMBOL
91#define TR_IMPORT_SYMBOL
92#define TR_LOCAL_SYMBOL
93#endif
94
95/** @} */ /* end of tr_export_visibility group */
96
97/* ------------------------------------------------------------------
98 * 2.2 Public API macro
99 * TR_DATASTRUCTURES_SHARED - defined by CMake when building shared library
100 * TR_DATASTRUCTURES_EXPORTS - defined by CMake when building the library itself
101 * (not defined when a user is consuming the library)
102 * ------------------------------------------------------------------ */
103/**
104 * @brief Marks a public API symbol for export or import
105 *
106 * When building the library as a shared library:
107 * - Expands to @c __declspec(dllexport) when building the library (MSVC)
108 * - Expands to @c __declspec(dllimport) when consuming the library (MSVC)
109 * - Expands to @c __attribute__((visibility("default"))) on GCC/Clang
110 *
111 * When building as a static library expands to nothing.
112 *
113 * Apply to all public API function declarations:
114 * @code
115 * TR_NODISCARD TR_API tr_result_t tr_stack_create(...);
116 * @endcode
117 */
118#if defined(TR_DATASTRUCTURES_SHARED)
119/* building or consuming as a shared library */
120#if defined(TR_DATASTRUCTURES_EXPORTS)
121/* we are building the library - export symbols */
122#define TR_API TR_EXPORT_SYMBOL
123#else
124/* we are consuming the library - import symbols */
125#define TR_API TR_IMPORT_SYMBOL
126#endif
127#else
128/* building or consuming as a static library - no decoration needed */
129#define TR_API
130#endif
131
132/* ------------------------------------------------------------------
133 * 2.3 Internal symbol macro
134 * Marks symbols that are internal to the library and should not
135 * be visible to consumers even when building shared
136 * ------------------------------------------------------------------ */
137/**
138 * @brief Marks a symbol as internal to the library
139 *
140 * Prevents the symbol from being visible to consumers of the library
141 * even when building as a shared library.
142 *
143 * - Expands to @c __attribute__((visibility("hidden"))) on GCC/Clang
144 * - Not supported on MSVC, expands to nothing
145 *
146 * Apply to internal functions that must be visible across translation
147 * units within the library but not to consumers:
148 * @code
149 * TR_INTERNAL void tr_internal_helper(void);
150 * @endcode
151 */
152#define TR_INTERNAL TR_LOCAL_SYMBOL
153
154/* ------------------------------------------------------------------
155 * 2.4 Deprecated symbol macro
156 * Marks public API functions as deprecated with a message
157 * ------------------------------------------------------------------ */
158/**
159 * @brief Marks a public API function as deprecated
160 *
161 * Emits a compiler warning when the marked function is used,
162 * with a message explaining the deprecation.
163 *
164 * - Expands to @c __declspec(deprecated(message)) on MSVC
165 * - Expands to @c __attribute__((deprecated(message))) on GCC/Clang
166 * - Expands to nothing on unknown compilers
167 *
168 * Example usage:
169 * @code
170 * TR_DEPRECATED("Use tr_stack_create instead")
171 * TR_API tr_result_t tr_stack_new(...);
172 * @endcode
173 *
174 * @param message String literal describing the deprecation reason
175 */
176#if defined(_MSC_VER)
177/* Microsoft Visual C++ compiler */
178#define TR_DEPRECATED(message) __declspec(deprecated(message))
179
180#elif defined(__GNUC__) && (__GNUC__ >= 4) || defined(__clang__)
181/* GCC version 4 or later, or Clang */
182#define TR_DEPRECATED(message) __attribute__((deprecated(message)))
183
184#else
185/* unknown compiler - degrade gracefully */
186#define TR_DEPRECATED(message)
187#endif
188
189/* ------------------------------------------------------------------
190 * 2.5 No discard macro
191 * Warns if the return value of a function is ignored
192 * Apply to all functions returning tr_result_t
193 * ------------------------------------------------------------------ */
194/**
195 * @brief Warns if the return value of a function is ignored
196 *
197 * Apply to all functions returning @ref tr_result_t to enforce
198 * error checking at the call site.
199 *
200 * - Expands to @c __attribute__((warn_unused_result)) on GCC/Clang
201 * - Expands to @c _Check_return_ on MSVC 2012 and later
202 * - Expands to nothing on unknown compilers
203 *
204 * Example usage:
205 * @code
206 * TR_NODISCARD TR_API tr_result_t tr_stack_push(...);
207 * @endcode
208 */
209#if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__clang__)
210/* GCC version 4 or later, or Clang */
211#define TR_NODISCARD __attribute__((warn_unused_result))
212#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
213/* Microsoft Visual C++ compiler version 2012 or later */
214#define TR_NODISCARD _Check_return_
215#else
216/* unknown compiler - degrade gracefully */
217#define TR_NODISCARD
218#endif
219
220// clang-format off
221/*****************************************************/
222
223/* 3 external declarations */
224/*****************************************************/
225/*****************************************************/
226
227/* 4 typedefs */
228/*****************************************************/
229/*****************************************************/
230
231/* 5 global variable declarations */
232/*****************************************************/
233/*****************************************************/
234
235/* 6 function prototypes */
236/*****************************************************/
237/*****************************************************/
238// clang-format on
239
240#ifdef __cplusplus
241}
242#endif
243
244#endif /* TR_EXPORT_H */