openat: don’t close (-1)
[gnulib.git] / lib / c++defs.h
blob7843359caa859aa03639dfe9abcca67dee70e4bf
1 /* C++ compatible function declaration macros.
2 Copyright (C) 2010-2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify it
5 under the terms of the GNU Lesser General Public License as published
6 by the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 #ifndef _GL_CXXDEFS_H
18 #define _GL_CXXDEFS_H
20 /* Begin/end the GNULIB_NAMESPACE namespace. */
21 #if defined __cplusplus && defined GNULIB_NAMESPACE
22 # define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
23 # define _GL_END_NAMESPACE }
24 #else
25 # define _GL_BEGIN_NAMESPACE
26 # define _GL_END_NAMESPACE
27 #endif
29 /* The three most frequent use cases of these macros are:
31 * For providing a substitute for a function that is missing on some
32 platforms, but is declared and works fine on the platforms on which
33 it exists:
35 #if @GNULIB_FOO@
36 # if !@HAVE_FOO@
37 _GL_FUNCDECL_SYS (foo, ...);
38 # endif
39 _GL_CXXALIAS_SYS (foo, ...);
40 _GL_CXXALIASWARN (foo);
41 #elif defined GNULIB_POSIXCHECK
42 ...
43 #endif
45 * For providing a replacement for a function that exists on all platforms,
46 but is broken/insufficient and needs to be replaced on some platforms:
48 #if @GNULIB_FOO@
49 # if @REPLACE_FOO@
50 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
51 # undef foo
52 # define foo rpl_foo
53 # endif
54 _GL_FUNCDECL_RPL (foo, ...);
55 _GL_CXXALIAS_RPL (foo, ...);
56 # else
57 _GL_CXXALIAS_SYS (foo, ...);
58 # endif
59 _GL_CXXALIASWARN (foo);
60 #elif defined GNULIB_POSIXCHECK
61 ...
62 #endif
64 * For providing a replacement for a function that exists on some platforms
65 but is broken/insufficient and needs to be replaced on some of them and
66 is additionally either missing or undeclared on some other platforms:
68 #if @GNULIB_FOO@
69 # if @REPLACE_FOO@
70 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
71 # undef foo
72 # define foo rpl_foo
73 # endif
74 _GL_FUNCDECL_RPL (foo, ...);
75 _GL_CXXALIAS_RPL (foo, ...);
76 # else
77 # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
78 _GL_FUNCDECL_SYS (foo, ...);
79 # endif
80 _GL_CXXALIAS_SYS (foo, ...);
81 # endif
82 _GL_CXXALIASWARN (foo);
83 #elif defined GNULIB_POSIXCHECK
84 ...
85 #endif
88 /* _GL_EXTERN_C declaration;
89 performs the declaration with C linkage. */
90 #if defined __cplusplus
91 # define _GL_EXTERN_C extern "C"
92 #else
93 # define _GL_EXTERN_C extern
94 #endif
96 /* _GL_EXTERN_C_FUNC declaration;
97 performs the declaration of a function with C linkage. */
98 #if defined __cplusplus
99 # define _GL_EXTERN_C_FUNC extern "C"
100 #else
101 /* In C mode, omit the 'extern' keyword, because attributes in bracket syntax
102 are not allowed between 'extern' and the return type (see gnulib-common.m4).
104 # define _GL_EXTERN_C_FUNC
105 #endif
107 /* _GL_FUNCDECL_RPL (func, rettype, parameters, [attributes]);
108 declares a replacement function, named rpl_func, with the given prototype,
109 consisting of return type, parameters, and attributes.
110 Although attributes are optional, the comma before them is required
111 for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW,
112 if needed, must be placed after the _GL_FUNCDECL_RPL invocation,
113 at the end of the declaration.
114 Examples:
115 _GL_FUNCDECL_RPL (free, void, (void *ptr), ) _GL_ATTRIBUTE_NOTHROW;
116 _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...),
117 _GL_ARG_NONNULL ((1)));
119 Note: Attributes, such as _GL_ATTRIBUTE_DEPRECATED, are supported in front
120 of a _GL_FUNCDECL_RPL invocation only in C mode, not in C++ mode. (That's
121 because
122 [[...]] extern "C" <declaration>;
123 is invalid syntax in C++.)
125 #define _GL_FUNCDECL_RPL(func,rettype,parameters,...) \
126 _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters, __VA_ARGS__)
127 #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \
128 _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters
130 /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]);
131 declares the system function, named func, with the given prototype,
132 consisting of return type, parameters, and attributes.
133 Although attributes are optional, the comma before them is required
134 for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW,
135 if needed, must be placed after the _GL_FUNCDECL_RPL invocation,
136 at the end of the declaration.
137 Examples:
138 _GL_FUNCDECL_SYS (getumask, mode_t, (void), ) _GL_ATTRIBUTE_NOTHROW;
139 _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD);
141 #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \
142 _GL_EXTERN_C_FUNC __VA_ARGS__ rettype func parameters
144 /* _GL_CXXALIAS_RPL (func, rettype, parameters);
145 declares a C++ alias called GNULIB_NAMESPACE::func
146 that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
147 Example:
148 _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
150 Wrapping rpl_func in an object with an inline conversion operator
151 avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
152 actually used in the program. */
153 #define _GL_CXXALIAS_RPL(func,rettype,parameters) \
154 _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
155 #if defined __cplusplus && defined GNULIB_NAMESPACE
156 # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
157 namespace GNULIB_NAMESPACE \
159 static const struct _gl_ ## func ## _wrapper \
161 typedef rettype (*type) parameters; \
163 inline operator type () const \
165 return ::rpl_func; \
167 } func = {}; \
169 _GL_EXTERN_C int _gl_cxxalias_dummy
170 #else
171 # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
172 _GL_EXTERN_C int _gl_cxxalias_dummy
173 #endif
175 /* _GL_CXXALIAS_MDA (func, rettype, parameters);
176 is to be used when func is a Microsoft deprecated alias, on native Windows.
177 It declares a C++ alias called GNULIB_NAMESPACE::func
178 that redirects to _func, if GNULIB_NAMESPACE is defined.
179 Example:
180 _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
182 #define _GL_CXXALIAS_MDA(func,rettype,parameters) \
183 _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)
185 /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
186 is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
187 except that the C function rpl_func may have a slightly different
188 declaration. A cast is used to silence the "invalid conversion" error
189 that would otherwise occur. */
190 #if defined __cplusplus && defined GNULIB_NAMESPACE
191 # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
192 namespace GNULIB_NAMESPACE \
194 static const struct _gl_ ## func ## _wrapper \
196 typedef rettype (*type) parameters; \
198 inline operator type () const \
200 return reinterpret_cast<type>(::rpl_func); \
202 } func = {}; \
204 _GL_EXTERN_C int _gl_cxxalias_dummy
205 #else
206 # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
207 _GL_EXTERN_C int _gl_cxxalias_dummy
208 #endif
210 /* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);
211 is like _GL_CXXALIAS_MDA (func, rettype, parameters);
212 except that the C function func may have a slightly different declaration.
213 A cast is used to silence the "invalid conversion" error that would
214 otherwise occur. */
215 #define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \
216 _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)
218 /* _GL_CXXALIAS_SYS (func, rettype, parameters);
219 declares a C++ alias called GNULIB_NAMESPACE::func
220 that redirects to the system provided function func, if GNULIB_NAMESPACE
221 is defined.
222 Example:
223 _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
225 Wrapping func in an object with an inline conversion operator
226 avoids a reference to func unless GNULIB_NAMESPACE::func is
227 actually used in the program. */
228 #if defined __cplusplus && defined GNULIB_NAMESPACE
229 # define _GL_CXXALIAS_SYS(func,rettype,parameters) \
230 namespace GNULIB_NAMESPACE \
232 static const struct _gl_ ## func ## _wrapper \
234 typedef rettype (*type) parameters; \
236 inline operator type () const \
238 return ::func; \
240 } func = {}; \
242 _GL_EXTERN_C int _gl_cxxalias_dummy
243 #else
244 # define _GL_CXXALIAS_SYS(func,rettype,parameters) \
245 _GL_EXTERN_C int _gl_cxxalias_dummy
246 #endif
248 /* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
249 is like _GL_CXXALIAS_SYS (func, rettype, parameters);
250 except that the C function func may have a slightly different declaration.
251 A cast is used to silence the "invalid conversion" error that would
252 otherwise occur. */
253 #if defined __cplusplus && defined GNULIB_NAMESPACE
254 # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
255 namespace GNULIB_NAMESPACE \
257 static const struct _gl_ ## func ## _wrapper \
259 typedef rettype (*type) parameters; \
261 inline operator type () const \
263 return reinterpret_cast<type>(::func); \
265 } func = {}; \
267 _GL_EXTERN_C int _gl_cxxalias_dummy
268 #else
269 # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
270 _GL_EXTERN_C int _gl_cxxalias_dummy
271 #endif
273 /* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
274 is like _GL_CXXALIAS_SYS (func, rettype, parameters);
275 except that the C function is picked among a set of overloaded functions,
276 namely the one with rettype2 and parameters2. Two consecutive casts
277 are used to silence the "cannot find a match" and "invalid conversion"
278 errors that would otherwise occur. */
279 #if defined __cplusplus && defined GNULIB_NAMESPACE
280 /* The outer cast must be a reinterpret_cast.
281 The inner cast: When the function is defined as a set of overloaded
282 functions, it works as a static_cast<>, choosing the designated variant.
283 When the function is defined as a single variant, it works as a
284 reinterpret_cast<>. The parenthesized cast syntax works both ways. */
285 # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
286 namespace GNULIB_NAMESPACE \
288 static const struct _gl_ ## func ## _wrapper \
290 typedef rettype (*type) parameters; \
292 inline operator type () const \
294 return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
296 } func = {}; \
298 _GL_EXTERN_C int _gl_cxxalias_dummy
299 #else
300 # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
301 _GL_EXTERN_C int _gl_cxxalias_dummy
302 #endif
304 /* _GL_CXXALIASWARN (func);
305 causes a warning to be emitted when ::func is used but not when
306 GNULIB_NAMESPACE::func is used. func must be defined without overloaded
307 variants. */
308 #if defined __cplusplus && defined GNULIB_NAMESPACE
309 # define _GL_CXXALIASWARN(func) \
310 _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
311 # define _GL_CXXALIASWARN_1(func,namespace) \
312 _GL_CXXALIASWARN_2 (func, namespace)
313 /* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
314 we enable the warning only when not optimizing. */
315 # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
316 # define _GL_CXXALIASWARN_2(func,namespace) \
317 _GL_WARN_ON_USE (func, \
318 "The symbol ::" #func " refers to the system function. " \
319 "Use " #namespace "::" #func " instead.")
320 # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING
321 # define _GL_CXXALIASWARN_2(func,namespace) \
322 extern __typeof__ (func) func
323 # else
324 # define _GL_CXXALIASWARN_2(func,namespace) \
325 _GL_EXTERN_C int _gl_cxxalias_dummy
326 # endif
327 #else
328 # define _GL_CXXALIASWARN(func) \
329 _GL_EXTERN_C int _gl_cxxalias_dummy
330 #endif
332 /* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
333 causes a warning to be emitted when the given overloaded variant of ::func
334 is used but not when GNULIB_NAMESPACE::func is used. */
335 #if defined __cplusplus && defined GNULIB_NAMESPACE
336 # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
337 _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
338 GNULIB_NAMESPACE)
339 # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
340 _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
341 /* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
342 we enable the warning only when not optimizing. */
343 # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
344 # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
345 _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \
346 "The symbol ::" #func " refers to the system function. " \
347 "Use " #namespace "::" #func " instead.")
348 # else
349 # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
350 _GL_EXTERN_C int _gl_cxxalias_dummy
351 # endif
352 #else
353 # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
354 _GL_EXTERN_C int _gl_cxxalias_dummy
355 #endif
357 #endif /* _GL_CXXDEFS_H */