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/>. */
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 }
25 # define _GL_BEGIN_NAMESPACE
26 # define _GL_END_NAMESPACE
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
37 _GL_FUNCDECL_SYS (foo, ...);
39 _GL_CXXALIAS_SYS (foo, ...);
40 _GL_CXXALIASWARN (foo);
41 #elif defined GNULIB_POSIXCHECK
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:
50 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
54 _GL_FUNCDECL_RPL (foo, ...);
55 _GL_CXXALIAS_RPL (foo, ...);
57 _GL_CXXALIAS_SYS (foo, ...);
59 _GL_CXXALIASWARN (foo);
60 #elif defined GNULIB_POSIXCHECK
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:
70 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
74 _GL_FUNCDECL_RPL (foo, ...);
75 _GL_CXXALIAS_RPL (foo, ...);
77 # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
78 _GL_FUNCDECL_SYS (foo, ...);
80 _GL_CXXALIAS_SYS (foo, ...);
82 _GL_CXXALIASWARN (foo);
83 #elif defined GNULIB_POSIXCHECK
88 /* _GL_EXTERN_C declaration;
89 performs the declaration with C linkage. */
90 #if defined __cplusplus
91 # define _GL_EXTERN_C extern "C"
93 # define _GL_EXTERN_C extern
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"
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
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.
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
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.
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.
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 \
169 _GL_EXTERN_C int _gl_cxxalias_dummy
171 # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
172 _GL_EXTERN_C int _gl_cxxalias_dummy
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.
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); \
204 _GL_EXTERN_C int _gl_cxxalias_dummy
206 # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
207 _GL_EXTERN_C int _gl_cxxalias_dummy
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
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
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 \
242 _GL_EXTERN_C int _gl_cxxalias_dummy
244 # define _GL_CXXALIAS_SYS(func,rettype,parameters) \
245 _GL_EXTERN_C int _gl_cxxalias_dummy
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
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); \
267 _GL_EXTERN_C int _gl_cxxalias_dummy
269 # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
270 _GL_EXTERN_C int _gl_cxxalias_dummy
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)); \
298 _GL_EXTERN_C int _gl_cxxalias_dummy
300 # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
301 _GL_EXTERN_C int _gl_cxxalias_dummy
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
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
324 # define _GL_CXXALIASWARN_2(func,namespace) \
325 _GL_EXTERN_C int _gl_cxxalias_dummy
328 # define _GL_CXXALIASWARN(func) \
329 _GL_EXTERN_C int _gl_cxxalias_dummy
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, \
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.")
349 # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
350 _GL_EXTERN_C int _gl_cxxalias_dummy
353 # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
354 _GL_EXTERN_C int _gl_cxxalias_dummy
357 #endif /* _GL_CXXDEFS_H */