xref: /illumos-gate/usr/src/head/README.cplusplus.md (revision 8c0afdd33bb297ecccc824153fb86a0cb0d929d2)
1*8c0afdd3SGordon Ross
2*8c0afdd3SGordon Ross<details>
3*8c0afdd3SGordon Ross<summary>License and copyright</summary>
4*8c0afdd3SGordon Ross
5*8c0afdd3SGordon RossCDDL HEADER START
6*8c0afdd3SGordon Ross
7*8c0afdd3SGordon RossThe contents of this file are subject to the terms of the
8*8c0afdd3SGordon RossCommon Development and Distribution License (the "License").
9*8c0afdd3SGordon RossYou may not use this file except in compliance with the License.
10*8c0afdd3SGordon Ross
11*8c0afdd3SGordon RossYou can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
12*8c0afdd3SGordon Rossor http://www.opensolaris.org/os/licensing.
13*8c0afdd3SGordon RossSee the License for the specific language governing permissions
14*8c0afdd3SGordon Rossand limitations under the License.
15*8c0afdd3SGordon Ross
16*8c0afdd3SGordon RossWhen distributing Covered Code, include this CDDL HEADER in each
17*8c0afdd3SGordon Rossfile and include the License file at usr/src/OPENSOLARIS.LICENSE.
18*8c0afdd3SGordon RossIf applicable, add the following below this CDDL HEADER, with the
19*8c0afdd3SGordon Rossfields enclosed by brackets "[]" replaced with your own identifying
20*8c0afdd3SGordon Rossinformation: Portions Copyright [yyyy] [name of copyright owner]
21*8c0afdd3SGordon Ross
22*8c0afdd3SGordon RossCDDL HEADER END
23*8c0afdd3SGordon Ross
24*8c0afdd3SGordon RossCopyright 2026 Gordon W. Ross
25*8c0afdd3SGordon Ross
26*8c0afdd3SGordon Ross</details>
27*8c0afdd3SGordon Ross
28*8c0afdd3SGordon Ross# Guidance for headers used in C++
29*8c0afdd3SGordon Ross
30*8c0afdd3SGordon Ross## Background
31*8c0afdd3SGordon Ross
32*8c0afdd3SGordon RossTwo models exist for how C system headers expose library names to C++:
33*8c0afdd3SGordon Ross
34*8c0afdd3SGordon Ross**std-primary**: ISO C library functions are declared inside `namespace std {}`.
35*8c0afdd3SGordon RossThe global namespace (`::`) is then populated via `using std::func` declarations.
36*8c0afdd3SGordon Ross
37*8c0afdd3SGordon Ross**global-primary**: ISO C library functions are declared directly in `::` via
38*8c0afdd3SGordon Ross`extern "C" {}`.  The `std::` namespace is then populated via `using ::func`
39*8c0afdd3SGordon Rossdeclarations.
40*8c0afdd3SGordon Ross
41*8c0afdd3SGordon RossFor future illumos header work, use the **global-primary** model.  It matches
42*8c0afdd3SGordon Rosswhat modern C++ toolchains expect, keeps the C declarations in their natural
43*8c0afdd3SGordon Rossnamespace, and gives a clear rule for what may be exposed in `namespace std`.
44*8c0afdd3SGordon Ross
45*8c0afdd3SGordon RossThe most important cautionary example is IL-15209.  In `<math.h>`, a
46*8c0afdd3SGordon Rossstd-primary layout let `using std::log` pull the float, double, and long double
47*8c0afdd3SGordon Rossoverloads into `::`, which made `log(int)` ambiguous.  The guidance below is
48*8c0afdd3SGordon Rossintended to prevent that class of problem when updating existing headers or
49*8c0afdd3SGordon Rossadding C++ support to new ones.
50*8c0afdd3SGordon Ross
51*8c0afdd3SGordon Ross---
52*8c0afdd3SGordon Ross
53*8c0afdd3SGordon Ross## Standards Basis: What Belongs in `::` vs. `namespace std`
54*8c0afdd3SGordon Ross
55*8c0afdd3SGordon RossFor a C header such as `<math.h>`, the practical guidance is:
56*8c0afdd3SGordon Ross
57*8c0afdd3SGordon Ross- put the C declarations in `::`
58*8c0afdd3SGordon Ross- populate `namespace std` only with names the C++ standard requires
59*8c0afdd3SGordon Ross- keep extension names in `::`, not in `namespace std`
60*8c0afdd3SGordon Ross- use Pattern B for math functions and other functions commonly called with
61*8c0afdd3SGordon Ross  integer arguments
62*8c0afdd3SGordon Ross
63*8c0afdd3SGordon RossThose rules follow from the C and C++ standards, summarized here.
64*8c0afdd3SGordon Ross
65*8c0afdd3SGordon Ross### The C standard
66*8c0afdd3SGordon Ross
67*8c0afdd3SGordon RossThe C standard defines only the `double` forms of math functions in `<math.h>`
68*8c0afdd3SGordon Ross(for example, `double log(double)`).  The `float` and `long double` variants
69*8c0afdd3SGordon Ross(`logf`, `logl`) are separate C function names, not overloads.  Therefore, the
70*8c0afdd3SGordon RossC standard places only the `double` form in `::`.
71*8c0afdd3SGordon Ross
72*8c0afdd3SGordon Ross### C++11 §D.5 `[depr.c.headers]`
73*8c0afdd3SGordon Ross
74*8c0afdd3SGordon RossC++11 Annex D §5 says:
75*8c0afdd3SGordon Ross
76*8c0afdd3SGordon Ross> Each C header `<name.h>` behaves as if each name placed in the standard
77*8c0afdd3SGordon Ross> library namespace by the corresponding `<cname>` header is placed within the
78*8c0afdd3SGordon Ross> global namespace scope.
79*8c0afdd3SGordon Ross
80*8c0afdd3SGordon RossRead literally, this suggests that `<math.h>` should also expose in `::` the
81*8c0afdd3SGordon Rossnames that `<cmath>` places in `namespace std`.  But the same paragraph makes
82*8c0afdd3SGordon Rossthe mechanism **implementation-defined**:
83*8c0afdd3SGordon Ross
84*8c0afdd3SGordon Ross> It is unspecified whether these names are first declared or defined within
85*8c0afdd3SGordon Ross> namespace scope of the namespace `std` and are then injected into the global
86*8c0afdd3SGordon Ross> namespace scope by explicit using-declarations.
87*8c0afdd3SGordon Ross
88*8c0afdd3SGordon RossIn illumos headers, that flexibility should be used in a way that keeps the
89*8c0afdd3SGordon Rossrules simple for future maintenance:
90*8c0afdd3SGordon Ross
91*8c0afdd3SGordon Ross- C declarations stay in `::`
92*8c0afdd3SGordon Ross- `namespace std` is populated explicitly, by `using ::func` and by C++-only
93*8c0afdd3SGordon Ross  inlines where needed
94*8c0afdd3SGordon Ross- the system header does not try to pre-populate `::` with every C++ overload
95*8c0afdd3SGordon Ross
96*8c0afdd3SGordon Ross### Pattern A: type variant overloads in `::`
97*8c0afdd3SGordon Ross
98*8c0afdd3SGordon RossPattern A puts C++-only type variant overloads in `::` alongside the
99*8c0afdd3SGordon RossC-standard form.  `using ::func` in `namespace std` then brings all overloads
100*8c0afdd3SGordon Rossat once.
101*8c0afdd3SGordon Ross
102*8c0afdd3SGordon RossUse Pattern A only for functions not commonly called with integer arguments.
103*8c0afdd3SGordon RossFor such functions, the layout is simple and there is no practical ambiguity
104*8c0afdd3SGordon Rossproblem.
105*8c0afdd3SGordon Ross
106*8c0afdd3SGordon Ross### Pattern B: type variant overloads in `namespace std` only
107*8c0afdd3SGordon Ross
108*8c0afdd3SGordon RossFor math functions, Pattern B is required:
109*8c0afdd3SGordon Ross
110*8c0afdd3SGordon Ross- `::` gets only what the C standard defines: for example, `double log(double)`.
111*8c0afdd3SGordon Ross- `namespace std` gets that form via `using ::log`, plus the float and long
112*8c0afdd3SGordon Ross  double overloads as C++-only inlines defined directly in `namespace std`.
113*8c0afdd3SGordon Ross
114*8c0afdd3SGordon RossThis avoids the IL-15209 failure mode.  C++11 `[c.math]` requires `<cmath>` to
115*8c0afdd3SGordon Rossprovide enough overloads for calls such as `log(1)` to work without ambiguity.
116*8c0afdd3SGordon RossOn GCC, the integer-covering support lives inside `namespace std`, not in `::`.
117*8c0afdd3SGordon RossIf the float and long double overloads are also placed in `::`, `log(1)` becomes
118*8c0afdd3SGordon Rossambiguous.  Pattern B keeps those overloads where the C++ library expects them.
119*8c0afdd3SGordon Ross
120*8c0afdd3SGordon RossGCC signals this expectation with `__CORRECT_ISO_CPP_MATH_H_PROTO`
121*8c0afdd3SGordon Ross(via `os_defines.h`).  When that macro is defined, libstdc++ expects the system
122*8c0afdd3SGordon Rossheader to have already provided the type variant overloads in `namespace std`
123*8c0afdd3SGordon Rossand skips adding its own.
124*8c0afdd3SGordon Ross
125*8c0afdd3SGordon Ross### Compatibility with other systems
126*8c0afdd3SGordon Ross
127*8c0afdd3SGordon RossThe illumos guidance here is intended to make header behavior more predictable
128*8c0afdd3SGordon Rossfor code written against other Unix-like systems and modern C++ libraries.
129*8c0afdd3SGordon Ross
130*8c0afdd3SGordon Ross**glibc (Linux) and FreeBSD** place no C++ overloads in `<math.h>` at all.
131*8c0afdd3SGordon RossTheir system headers declare the C functions in `::`, and their C++ libraries
132*8c0afdd3SGordon Rosshandle the overload sets in `<cmath>`.
133*8c0afdd3SGordon Ross([glibc math/math.h](https://github.com/bminor/glibc/blob/glibc-2.42/math/math.h),
134*8c0afdd3SGordon Ross[FreeBSD lib/msun/src/math.h](https://github.com/freebsd/freebsd-src/blob/stable/14/lib/msun/src/math.h))
135*8c0afdd3SGordon Ross
136*8c0afdd3SGordon Ross**LLVM libc++** uses a self-contained arrangement based on an internal
137*8c0afdd3SGordon Ross`std::__math` namespace.  It does not rely on illumos-style system header
138*8c0afdd3SGordon Rosscoordination, but it still follows the general expectation that the C library
139*8c0afdd3SGordon Rossdeclarations live in `::` and the C++ library manages the overload model.
140*8c0afdd3SGordon Ross([libcxx/include/math.h](https://github.com/llvm/llvm-project/blob/release/20.x/libcxx/include/math.h),
141*8c0afdd3SGordon Ross[libcxx/include/cmath](https://github.com/llvm/llvm-project/blob/release/20.x/libcxx/include/cmath),
142*8c0afdd3SGordon Ross[libcxx/include/__math/trigonometric_functions.h](https://github.com/llvm/llvm-project/blob/release/20.x/libcxx/include/__math/trigonometric_functions.h))
143*8c0afdd3SGordon Ross
144*8c0afdd3SGordon Ross**libstdc++** uses Pattern B by default.  Its `<cmath>` puts the type variant
145*8c0afdd3SGordon Rossoverloads in `namespace std`, and on Solaris or illumos it uses
146*8c0afdd3SGordon Ross`__CORRECT_ISO_CPP_MATH_H_PROTO` to decide whether the system header already
147*8c0afdd3SGordon Rossdid that work.
148*8c0afdd3SGordon Ross([libstdc++-v3/include/c_global/cmath](https://github.com/gcc-mirror/gcc/blob/releases/gcc-14/libstdc++-v3/include/c_global/cmath),
149*8c0afdd3SGordon Ross[libstdc++-v3/include/bits/std_abs.h](https://github.com/gcc-mirror/gcc/blob/releases/gcc-14/libstdc++-v3/include/bits/std_abs.h))
150*8c0afdd3SGordon Ross
151*8c0afdd3SGordon RossFor illumos, the key compatibility point is with **libstdc++**.  If the system
152*8c0afdd3SGordon Rossheader uses global-primary structure and Pattern B for math, the system header
153*8c0afdd3SGordon Rossand the C++ library cooperate cleanly.
154*8c0afdd3SGordon Ross([libstdc++-v3/config/os/solaris/os_defines.h](https://github.com/gcc-mirror/gcc/blob/releases/gcc-14/libstdc++-v3/config/os/solaris/os_defines.h))
155*8c0afdd3SGordon Ross
156*8c0afdd3SGordon Ross### In what namespace are extensions?
157*8c0afdd3SGordon Ross
158*8c0afdd3SGordon RossExtension symbols (those gated on `__EXTENSIONS__`, `_XOPEN_SOURCE`, or
159*8c0afdd3SGordon Rosssimilar macros) are declared in the C++ global namespace (`::`) only.
160*8c0afdd3SGordon Ross`namespace std` is populated exclusively with names the C++ standard requires.
161*8c0afdd3SGordon RossThis keeps the rule simple: if a name is an extension, it belongs in `::`.
162*8c0afdd3SGordon Ross
163*8c0afdd3SGordon Ross---
164*8c0afdd3SGordon Ross
165*8c0afdd3SGordon Ross## Why Change from std-primary to global-primary?
166*8c0afdd3SGordon Ross
167*8c0afdd3SGordon RossThe older illumos headers were developed when the C and C++ standards were
168*8c0afdd3SGordon Rossstill evolving and when SunPro was the primary compiler.  Today the important
169*8c0afdd3SGordon Rossgoal is to make future header work predictable and compatible with modern C++
170*8c0afdd3SGordon Rosstoolchains.  Adopting the global-primary model gives several advantages:
171*8c0afdd3SGordon Ross
172*8c0afdd3SGordon Ross1. **Standards conformance.**  C declarations belong in `::` by definition; that
173*8c0afdd3SGordon Ross   is what `extern "C"` means.  The std-primary model placed them in
174*8c0afdd3SGordon Ross   `namespace std` as a primary residence, which is non-standard.  Global-primary
175*8c0afdd3SGordon Ross   aligns with both the C standard (declarations in `::`) and the C++ standard
176*8c0afdd3SGordon Ross   (`namespace std` contains what `<cname>` is required to provide).
177*8c0afdd3SGordon Ross
178*8c0afdd3SGordon Ross2. **Mismatch with other platforms.**  glibc, FreeBSD, macOS, and other major
179*8c0afdd3SGordon Ross   Unix systems use global-primary: C declarations in `::`, with the C++ library
180*8c0afdd3SGordon Ross   responsible for populating `namespace std`.  illumos being different causes
181*8c0afdd3SGordon Ross   portability friction for application code.
182*8c0afdd3SGordon Ross
183*8c0afdd3SGordon Ross3. **Extension pollution of `namespace std`.**  In the std-primary model it is
184*8c0afdd3SGordon Ross   easy to accidentally declare extension symbols (those gated on `__EXTENSIONS__`
185*8c0afdd3SGordon Ross   or `_XOPEN_SOURCE`) inside `namespace std`.  The global-primary model makes
186*8c0afdd3SGordon Ross   the boundary explicit: extensions go in `::` only, and `namespace std` is
187*8c0afdd3SGordon Ross   populated exclusively via deliberate `using ::func` aliases.
188*8c0afdd3SGordon Ross
189*8c0afdd3SGordon Ross4. **Bugs from over-population of `::`.**  The outer headers use `using std::func`
190*8c0afdd3SGordon Ross   to pull names from `namespace std` into `::`.  When `namespace std` contains
191*8c0afdd3SGordon Ross   type variant overloads (float, long double), all of them land in `::` at once,
192*8c0afdd3SGordon Ross   with no integer-covering template to resolve ambiguous calls.  IL-15209
193*8c0afdd3SGordon Ross   (`log(int)` ambiguous) is one instance of this class of bug.
194*8c0afdd3SGordon Ross
195*8c0afdd3SGordon Ross---
196*8c0afdd3SGordon Ross
197*8c0afdd3SGordon Ross## Header Structure
198*8c0afdd3SGordon Ross
199*8c0afdd3SGordon RossSee the [`header-template.h`](#Header-template) below for the canonical
200*8c0afdd3SGordon Rossannotated example.  Each ISO header is structured into six sections:
201*8c0afdd3SGordon Ross
202*8c0afdd3SGordon Ross### Core principle
203*8c0afdd3SGordon Ross
204*8c0afdd3SGordon RossThe **global namespace is primary**.  `std::` is secondary, populated only
205*8c0afdd3SGordon Rosswith what the C++ standard requires.
206*8c0afdd3SGordon Ross
207*8c0afdd3SGordon Rossillumos headers are currently in transition.  Many still follow the old
208*8c0afdd3SGordon Rossstd-primary model.  See [Status by header](#status-by-header) for the current
209*8c0afdd3SGordon Rossstate of each header.
210*8c0afdd3SGordon Ross
211*8c0afdd3SGordon Ross### Section 1: Unconditional C declarations (C++ global namespace)
212*8c0afdd3SGordon RossStandard C library functions are declared with C linkage, visible to both C
213*8c0afdd3SGordon Rossand C++ translation units:
214*8c0afdd3SGordon Ross
215*8c0afdd3SGordon Ross```cpp
216*8c0afdd3SGordon Ross#ifdef __cplusplus
217*8c0afdd3SGordon Rossextern "C" {
218*8c0afdd3SGordon Ross#endif
219*8c0afdd3SGordon Ross
220*8c0afdd3SGordon Rossextern double log(double);
221*8c0afdd3SGordon Rossextern double acos(double);
222*8c0afdd3SGordon Ross/* ... */
223*8c0afdd3SGordon Ross
224*8c0afdd3SGordon Ross#ifdef __cplusplus
225*8c0afdd3SGordon Ross}  /* extern "C" */
226*8c0afdd3SGordon Ross#endif
227*8c0afdd3SGordon Ross```
228*8c0afdd3SGordon Ross
229*8c0afdd3SGordon RossThe outer header (`<math.h>`) needs no `using std::log` lines; `::log` is
230*8c0afdd3SGordon Rossalready there from the declaration.
231*8c0afdd3SGordon Ross
232*8c0afdd3SGordon Ross### Section 2: Conditional C declarations (C++ global namespace)
233*8c0afdd3SGordon RossFunctions gated on environment macros (`_C99_SOURCE`, `_XOPEN_SOURCE`,
234*8c0afdd3SGordon Ross`__EXTENSIONS__`, etc.) declared in `::` under the appropriate guards.
235*8c0afdd3SGordon RossExtension symbols (`__EXTENSIONS__`) are **not** aliased into `namespace std`.
236*8c0afdd3SGordon Ross
237*8c0afdd3SGordon Ross### Section 3: C-linkage helpers for C++ only (C++ global namespace)
238*8c0afdd3SGordon RossType-variant C functions needed solely by C++ overloaded inlines in Section 4,
239*8c0afdd3SGordon Rosswith no purpose in C translation units.  For `<math.h>` this means the `*f`
240*8c0afdd3SGordon Rossand `*l` variants, declared inside the `extern "C"` block but guarded by
241*8c0afdd3SGordon Ross`#ifdef __cplusplus`:
242*8c0afdd3SGordon Ross
243*8c0afdd3SGordon Ross```cpp
244*8c0afdd3SGordon Ross#ifdef __cplusplus
245*8c0afdd3SGordon Rossextern float  acosf(float);
246*8c0afdd3SGordon Rossextern long double acosl(long double);
247*8c0afdd3SGordon Ross#endif
248*8c0afdd3SGordon Ross```
249*8c0afdd3SGordon Ross
250*8c0afdd3SGordon Ross### Sections 4–6: C++ block (always a separate top-level `extern "C++"`)
251*8c0afdd3SGordon Ross
252*8c0afdd3SGordon RossThe `extern "C++"` block is **never nested inside `extern "C"`**.  It opens
253*8c0afdd3SGordon Rossafter the `extern "C"` block closes.
254*8c0afdd3SGordon Ross
255*8c0afdd3SGordon Ross**Section 4: C++ overloaded inlines (C++ global namespace or `namespace std`).**
256*8c0afdd3SGordon RossWhere the inlines live depends on which pattern applies
257*8c0afdd3SGordon Ross(see [Standards Basis](#standards-basis-what-belongs-in--vs-namespace-std)):
258*8c0afdd3SGordon Ross
259*8c0afdd3SGordon Ross- **Pattern A**: inlines go in the C++ global namespace (`extern "C++"` at
260*8c0afdd3SGordon Ross  file scope, outside any `namespace` block).  A subsequent `using ::func`
261*8c0afdd3SGordon Ross  in Section 6 brings all overloads into `namespace std` at once.  Safe only
262*8c0afdd3SGordon Ross  for functions not commonly called with integer arguments.
263*8c0afdd3SGordon Ross- **Pattern B**: no inlines here.  Inlines are defined directly inside
264*8c0afdd3SGordon Ross  `namespace std` in Section 6.  Required for math functions (`log`, `sin`,
265*8c0afdd3SGordon Ross  etc.) to prevent `log(1)` ambiguity.
266*8c0afdd3SGordon Ross
267*8c0afdd3SGordon Ross```cpp
268*8c0afdd3SGordon Ross#if __cplusplus >= 199711L
269*8c0afdd3SGordon Rossextern "C++" {
270*8c0afdd3SGordon Ross
271*8c0afdd3SGordon Ross    /* Pattern A: global namespace; acos(1) is unambiguous */
272*8c0afdd3SGordon Ross    inline float       acos(float __x)       { return acosf(__x); }
273*8c0afdd3SGordon Ross    inline long double acos(long double __x) { return acosl(__x); }
274*8c0afdd3SGordon Ross
275*8c0afdd3SGordon Ross    /* Pattern B functions have no inlines here; see Section 6 */
276*8c0afdd3SGordon Ross```
277*8c0afdd3SGordon Ross
278*8c0afdd3SGordon Ross**Section 5: C++ overloads for conditionally-exposed functions (C++ global
279*8c0afdd3SGordon Rossnamespace).**  Same `extern "C++"` block.  Type variant inlines for functions
280*8c0afdd3SGordon Rossdeclared in Section 2, placed in the C++ global namespace and guarded by the
281*8c0afdd3SGordon Rosssame environment macro conditions (`_C99_SOURCE`, `_XOPEN_SOURCE`,
282*8c0afdd3SGordon Ross`__EXTENSIONS__`, etc.) as their Section 2 declarations:
283*8c0afdd3SGordon Ross
284*8c0afdd3SGordon Ross```cpp
285*8c0afdd3SGordon Ross#if defined(__EXTENSIONS__)
286*8c0afdd3SGordon Ross    inline float       acospi(float __x)       { return acospif(__x); }
287*8c0afdd3SGordon Ross    inline long double acospi(long double __x) { return acospil(__x); }
288*8c0afdd3SGordon Ross#endif
289*8c0afdd3SGordon Ross```
290*8c0afdd3SGordon Ross
291*8c0afdd3SGordon Ross**Section 6: `namespace std`** (same `extern "C++"` block).  Populated with
292*8c0afdd3SGordon Rossonly the names the C++ standard requires.  No extensions.  Pattern B inlines
293*8c0afdd3SGordon Rossare defined here inside `namespace std`:
294*8c0afdd3SGordon Ross
295*8c0afdd3SGordon Ross```cpp
296*8c0afdd3SGordon Ross    namespace std {
297*8c0afdd3SGordon Ross        using ::acos;            /* Pattern A: brings double+float+ldbl */
298*8c0afdd3SGordon Ross
299*8c0afdd3SGordon Ross        using ::log;             /* Pattern B: double form only */
300*8c0afdd3SGordon Ross        inline float       log(float __x)       { return logf(__x); }
301*8c0afdd3SGordon Ross        inline long double log(long double __x) { return logl(__x); }
302*8c0afdd3SGordon Ross    }
303*8c0afdd3SGordon Ross
304*8c0afdd3SGordon Ross}  /* extern "C++" */
305*8c0afdd3SGordon Ross#endif  /* __cplusplus >= 199711L */
306*8c0afdd3SGordon Ross```
307*8c0afdd3SGordon Ross
308*8c0afdd3SGordon Ross## Header template
309*8c0afdd3SGordon Ross
310*8c0afdd3SGordon Ross```
311*8c0afdd3SGordon Ross/*
312*8c0afdd3SGordon Ross *  top matter (CDDL, copyrights)
313*8c0afdd3SGordon Ross */
314*8c0afdd3SGordon Ross
315*8c0afdd3SGordon Ross/*
316*8c0afdd3SGordon Ross * Global-primary namespace model
317*8c0afdd3SGordon Ross * --------------------------------
318*8c0afdd3SGordon Ross * All C library function declarations go in the global namespace (::)
319*8c0afdd3SGordon Ross * inside extern "C" {}.  The C++ standard namespace (std::) is then
320*8c0afdd3SGordon Ross * populated exclusively via "using ::" aliases, never by redeclaring
321*8c0afdd3SGordon Ross * symbols inside "namespace std {}".
322*8c0afdd3SGordon Ross *
323*8c0afdd3SGordon Ross * C++ requires additional type variant overloads (e.g., math.h's float
324*8c0afdd3SGordon Ross * and long double forms of acos).  These are:
325*8c0afdd3SGordon Ross *   - Forward-declared with C linkage inside extern "C" (Section 3)
326*8c0afdd3SGordon Ross *   - Provided as overloaded inlines via extern "C++" (Sections 4 or 6)
327*8c0afdd3SGordon Ross *   - Brought into std:: in Section 6
328*8c0afdd3SGordon Ross *
329*8c0afdd3SGordon Ross * There are two patterns for where the inlines live:
330*8c0afdd3SGordon Ross *
331*8c0afdd3SGordon Ross *   Pattern A: inlines in :: (global namespace).
332*8c0afdd3SGordon Ross *     "using ::func" in namespace std then brings all type variant
333*8c0afdd3SGordon Ross *     overloads into std:: in one declaration.  Use this when the
334*8c0afdd3SGordon Ross *     function is unlikely to be called with integer arguments.
335*8c0afdd3SGordon Ross *
336*8c0afdd3SGordon Ross *   Pattern B: inlines in namespace std only.
337*8c0afdd3SGordon Ross *     "using ::func" brings only the C-standard (e.g., double) form
338*8c0afdd3SGordon Ross *     into std::.  Type variant inlines are defined directly in
339*8c0afdd3SGordon Ross *     namespace std.  Use this for functions that may be called with
340*8c0afdd3SGordon Ross *     integer arguments: if type variant overloads were in ::, a call
341*8c0afdd3SGordon Ross *     like log(1) would be ambiguous.  Math functions use Pattern B.
342*8c0afdd3SGordon Ross *
343*8c0afdd3SGordon Ross * The extern "C++" block is always separate from (never nested inside)
344*8c0afdd3SGordon Ross * extern "C" {}.
345*8c0afdd3SGordon Ross */
346*8c0afdd3SGordon Ross
347*8c0afdd3SGordon Ross#ifndef _INCLUDE_GUARD_
348*8c0afdd3SGordon Ross#define _INCLUDE_GUARD_
349*8c0afdd3SGordon Ross
350*8c0afdd3SGordon Ross/* prerequisite includes etc. */
351*8c0afdd3SGordon Ross#include <sys/feature_tests.h>
352*8c0afdd3SGordon Ross
353*8c0afdd3SGordon Ross/*
354*8c0afdd3SGordon Ross * Section 1: Unconditional C linkage declarations (global namespace ::)
355*8c0afdd3SGordon Ross *
356*8c0afdd3SGordon Ross * Visible to both C and C++.  For example, math.h declares
357*8c0afdd3SGordon Ross * `double acos(double)` here.
358*8c0afdd3SGordon Ross */
359*8c0afdd3SGordon Ross#ifdef	__cplusplus
360*8c0afdd3SGordon Rossextern "C" {
361*8c0afdd3SGordon Ross#endif
362*8c0afdd3SGordon Ross
363*8c0afdd3SGordon Rossextern double acos(double);
364*8c0afdd3SGordon Ross
365*8c0afdd3SGordon Ross/*
366*8c0afdd3SGordon Ross * Section 2: Conditionally exposed declarations (global namespace ::)
367*8c0afdd3SGordon Ross *
368*8c0afdd3SGordon Ross * Functions exposed based on the compilation environment: C standard
369*8c0afdd3SGordon Ross * version (_C99_SOURCE, _C11_SOURCE), feature-test macros
370*8c0afdd3SGordon Ross * (_XOPEN_SOURCE, _POSIX_SOURCE, __EXTENSIONS__), and similar.
371*8c0afdd3SGordon Ross * Some of these may be aliased into std:: in Section 6.
372*8c0afdd3SGordon Ross */
373*8c0afdd3SGordon Ross#if defined(_C99_SOURCE) || defined(_XOPEN_SOURCE)
374*8c0afdd3SGordon Ross
375*8c0afdd3SGordon Ross/* extern double foo(double); */
376*8c0afdd3SGordon Ross
377*8c0afdd3SGordon Ross#endif	/* _C99_SOURCE || _XOPEN_SOURCE (and others) */
378*8c0afdd3SGordon Ross
379*8c0afdd3SGordon Ross#if defined(__EXTENSIONS__)
380*8c0afdd3SGordon Ross
381*8c0afdd3SGordon Rossextern double acospi(double);
382*8c0afdd3SGordon Ross
383*8c0afdd3SGordon Ross#endif	/* __EXTENSIONS__ */
384*8c0afdd3SGordon Ross
385*8c0afdd3SGordon Ross/*
386*8c0afdd3SGordon Ross * Section 3: C-linkage functions needed only by the C++ overloaded
387*8c0afdd3SGordon Ross * inlines or templates in Section 4; they have no use in C
388*8c0afdd3SGordon Ross * translation units.  Functions from Section 2 that also need
389*8c0afdd3SGordon Ross * type variant helpers belong here too, guarded by the same
390*8c0afdd3SGordon Ross * feature-test conditions as their Section 2 declarations.
391*8c0afdd3SGordon Ross * For example, math.h adds `float acosf(float)` and
392*8c0afdd3SGordon Ross * `long double acosl(long double)` here for use in the argument
393*8c0afdd3SGordon Ross * overloads in Section 4.
394*8c0afdd3SGordon Ross */
395*8c0afdd3SGordon Ross#ifdef	__cplusplus
396*8c0afdd3SGordon Rossextern float acosf(float);
397*8c0afdd3SGordon Rossextern long double acosl(long double);
398*8c0afdd3SGordon Ross#endif	/* __cplusplus */
399*8c0afdd3SGordon Ross
400*8c0afdd3SGordon Ross#ifdef	__cplusplus
401*8c0afdd3SGordon Ross}  /* extern "C" */
402*8c0afdd3SGordon Ross#endif
403*8c0afdd3SGordon Ross
404*8c0afdd3SGordon Ross/*
405*8c0afdd3SGordon Ross * Section 4: C++ overloaded inlines (Pattern A: inlines in ::).
406*8c0afdd3SGordon Ross *
407*8c0afdd3SGordon Ross * This block is entirely separate from extern "C" above.
408*8c0afdd3SGordon Ross * Use Pattern A when the function is not commonly called with
409*8c0afdd3SGordon Ross * integer arguments.  For example, acos(1) compiles fine even
410*8c0afdd3SGordon Ross * with type variant overloads in :: because there is no ambiguity
411*8c0afdd3SGordon Ross * in practice.
412*8c0afdd3SGordon Ross *
413*8c0afdd3SGordon Ross * For functions that ARE commonly called with integer arguments
414*8c0afdd3SGordon Ross * (most math functions), use Pattern B: omit the inlines here
415*8c0afdd3SGordon Ross * and define them directly inside namespace std in Section 6.
416*8c0afdd3SGordon Ross */
417*8c0afdd3SGordon Ross#if __cplusplus >= 199711L
418*8c0afdd3SGordon Rossextern "C++" {
419*8c0afdd3SGordon Ross#undef	__X
420*8c0afdd3SGordon Ross#undef	__Y
421*8c0afdd3SGordon Ross
422*8c0afdd3SGordon Ross	inline float acos(float __X) { return acosf(__X); }
423*8c0afdd3SGordon Ross	inline long double acos(long double __X) { return acosl(__X); }
424*8c0afdd3SGordon Ross
425*8c0afdd3SGordon Ross/*
426*8c0afdd3SGordon Ross * Section 5: C++ overloads for conditionally-exposed functions
427*8c0afdd3SGordon Ross * (C++ global namespace).
428*8c0afdd3SGordon Ross *
429*8c0afdd3SGordon Ross * Type variant inlines for functions declared in Section 2, guarded
430*8c0afdd3SGordon Ross * by the same environment macro conditions as their Section 2
431*8c0afdd3SGordon Ross * declarations.
432*8c0afdd3SGordon Ross */
433*8c0afdd3SGordon Ross#if defined(__EXTENSIONS__)
434*8c0afdd3SGordon Ross#undef	__X
435*8c0afdd3SGordon Ross
436*8c0afdd3SGordon Ross	inline float acospi(float __X) { return acospif(__X); }
437*8c0afdd3SGordon Ross	inline long double acospi(long double __X) { return acospil(__X); }
438*8c0afdd3SGordon Ross
439*8c0afdd3SGordon Ross#endif	/* __EXTENSIONS__ */
440*8c0afdd3SGordon Ross
441*8c0afdd3SGordon Ross/*
442*8c0afdd3SGordon Ross * Section 6: namespace std population.
443*8c0afdd3SGordon Ross *
444*8c0afdd3SGordon Ross * Only declarations codified by C++ standards are aliased into std::.
445*8c0afdd3SGordon Ross * Aliases for Section 2 (conditionally exposed, standards-codified)
446*8c0afdd3SGordon Ross * functions may also appear here, guarded by the same conditions as
447*8c0afdd3SGordon Ross * Section 2.
448*8c0afdd3SGordon Ross *
449*8c0afdd3SGordon Ross * Pattern A: "using ::" brings all type variant overloads into std::
450*8c0afdd3SGordon Ross * in one declaration; used when inlines are in :: (Section 4).
451*8c0afdd3SGordon Ross *
452*8c0afdd3SGordon Ross * Pattern B (math functions): "using ::" brings only the C-standard
453*8c0afdd3SGordon Ross * form; type variant inlines are defined directly here in namespace
454*8c0afdd3SGordon Ross * std to avoid ambiguity when called with integer args.
455*8c0afdd3SGordon Ross */
456*8c0afdd3SGordon Rossnamespace std {
457*8c0afdd3SGordon Ross	/* Pattern A example: */
458*8c0afdd3SGordon Ross	using ::acos;
459*8c0afdd3SGordon Ross
460*8c0afdd3SGordon Ross	/* Pattern B example (math.h style): */
461*8c0afdd3SGordon Ross	using ::log;	/* double form only in :: */
462*8c0afdd3SGordon Ross	inline float log(float __X) { return logf(__X); }
463*8c0afdd3SGordon Ross	inline long double log(long double __X) { return logl(__X); }
464*8c0afdd3SGordon Ross
465*8c0afdd3SGordon Ross}  /* namespace std */
466*8c0afdd3SGordon Ross
467*8c0afdd3SGordon Ross}  /* extern "C++" */
468*8c0afdd3SGordon Ross#endif	/* __cplusplus >= 199711L */
469*8c0afdd3SGordon Ross
470*8c0afdd3SGordon Ross#endif	/* _INCLUDE_GUARD_ */
471*8c0afdd3SGordon Ross```
472