Name Date Size #Lines LOC

..--

arpa/H--1,7461,125

audio/H--13558

iso/H--3,4181,994

kerberosv5/H--18218

protocols/H--670325

rpcsvc/H--8,5715,311

uuid/H--8223

.gitignoreH A D20-Mar-2025667 2926

MakefileH A D18-Aug-20258.1 KiB442332

README.cplusplus.mdH A D29-May-202617.9 KiB472367

aio.hH A D03-Aug-20144.5 KiB14497

alloca.hH A D03-Aug-20142.1 KiB7217

apptrace.hH A D11-Feb-20223.5 KiB12158

apptrace_impl.hH A D03-Aug-20141.7 KiB6626

ar.hH A D14-Jun-20172.5 KiB8422

archives.hH A D14-Jun-20177.9 KiB286131

assert.hH A D21-Nov-20252 KiB6212

atomic.hH A D11-Feb-20221 KiB334

attr.hH A D03-Aug-20141.4 KiB4916

auth_attr.hH A D03-Aug-20142.9 KiB10450

auth_list.hH A D03-Aug-20173.2 KiB9347

complex.hH A D26-Nov-20144.7 KiB13192

config_admin.hH A D02-Jul-20177.1 KiB262144

cpio.hH A D14-Jun-20171.6 KiB6530

crypt.hH A D14-Jun-20171.9 KiB6525

ctype.hH A D14-Jun-20173.1 KiB12067

deflt.hH A D14-Jun-20172.4 KiB8327

devid.hH A D02-Jul-20172 KiB6631

devmgmt.hH A D14-Jun-20174.1 KiB17742

devpoll.hH A D11-Feb-20221,011 334

dial.hH A D14-Jun-20172.7 KiB8744

dirent.hH A D02-Jul-20177 KiB225139

dlfcn.hH A D11-Dec-20247.8 KiB232125

door.hH A D19-Nov-20092 KiB7735

elf.hH A D14-Jun-2017975 324

endian.hH A D05-Jun-20161.7 KiB7542

err.hH A D02-Dec-20231.9 KiB6024

errno.hH A D25-Aug-20181.8 KiB7627

euc.hH A D14-Jun-20171.7 KiB6424

exacct.hH A D11-Feb-20223.1 KiB8938

exacct_impl.hH A D11-Feb-20221.9 KiB6633

exec_attr.hH A D03-Aug-20144.3 KiB14876

execinfo.hH A D03-Aug-20141.4 KiB4912

fatal.hH A D14-Jun-20171.4 KiB5523

fcntl.hH A D14-Jun-20175.8 KiB168117

fenv.hH A D29-Apr-20195.1 KiB240157

float.hH A D14-Jun-20173.7 KiB13980

floatingpoint.hH A D29-Apr-20196.3 KiB202111

fmtmsg.hH A D14-Jun-20174.7 KiB19551

fnmatch.hH A D14-Aug-20171.9 KiB5719

fts.hH A D07-Aug-20185.4 KiB14397

ftw.hH A D14-Jun-20174.8 KiB16599

gelf.hH A D11-Feb-20224.4 KiB14679

getopt.hH A D04-Feb-20202.2 KiB8828

getwidth.hH A D14-Jun-20171.2 KiB4911

glob.hH A D29-Oct-20156.5 KiB18371

grp.hH A D19-Nov-20205.5 KiB16067

iconv.hH A D03-Aug-20141.6 KiB5823

ieeefp.hH A D03-Aug-20149.1 KiB301132

ifaddrs.hH A D20-May-20222.9 KiB9538

inttypes.hH A D03-Aug-20143.9 KiB12662

iso646.hH A D11-Feb-20221.5 KiB5922

klpd.hH A D11-Feb-20221.5 KiB5221

langinfo.hH A D02-Jan-20254.4 KiB16382

lastlog.hH A D14-Jun-20171.5 KiB6121

lber.hH A D11-Feb-20226.4 KiB217150

ldap.hH A D02-Jul-201755.1 KiB1,583925

libelf.hH A D02-Jul-20175.1 KiB225145

libgen.hH A D14-Jun-20173.5 KiB12470

libintl.hH A D13-Mar-20263.2 KiB10041

libw.hH A D14-Jun-20171.4 KiB5420

libzonecfg.hH A D26-Feb-202222.3 KiB620426

limits.hH A D02-Mar-202510.8 KiB340200

linenum.hH A D14-Jun-20171.6 KiB6120

link.hH A D02-Mar-20259.1 KiB299171

listen.hH A D26-Feb-20223.3 KiB13736

locale.hH A D12-Apr-20252.9 KiB10645

macros.hH A D02-Jul-20172.7 KiB10428

malloc.hH A D14-Jun-20172.6 KiB9145

math.hH A D26-Apr-20266.7 KiB249145

memory.hH A D20-Jan-20262.1 KiB8239

mon.hH A D02-Mar-20251.9 KiB7932

monetary.hH A D03-Aug-20141.5 KiB5821

mp.hH A D14-Jun-20172.1 KiB7531

mqueue.hH A D03-Aug-20142.5 KiB8546

nan.hH A D14-Jun-20173.1 KiB13764

ndbm.hH A D14-Jun-20173.1 KiB11961

ndpd.hH A D02-Jul-20174.9 KiB150104

netconfig.hH A D14-Jun-20171,023 324

netdb.hH A D14-Jun-201714.1 KiB405237

netdir.hH A D02-Jul-20175.4 KiB17081

nl_types.hH A D02-Jul-20173.5 KiB11756

nlist.hH A D14-Jun-20171.4 KiB5218

note.hH A D11-Feb-20221.6 KiB5411

nss_common.hH A D26-Feb-202217.2 KiB471132

nss_dbdefs.hH A D21-Jun-202128.1 KiB835402

nss_netdir.hH A D03-Aug-20143.3 KiB14497

nsswitch.hH A D02-Jul-20173.9 KiB13882

paths.hH A D03-Jul-20112.8 KiB7835

pcsample.hH A D03-Aug-20141.2 KiB4811

pfmt.hH A D14-Jun-20171.9 KiB8341

pkgdev.hH A D02-Jul-20171.3 KiB5423

pkginfo.hH A D02-Jul-20171.5 KiB6328

pkglocs.hH A D14-Jun-20171.2 KiB4313

pkgstrct.hH A D14-Jun-20172.1 KiB10462

pkgtrans.hH A D14-Jun-20171.2 KiB4515

poll.hH A D14-Jun-20171.6 KiB6019

port.hH A D11-Feb-20221.5 KiB5519

priv.hH A D03-Aug-20142.9 KiB8744

priv_utils.hH A D11-Feb-20222.6 KiB9519

proc_service.hH A D25-Jan-20234.5 KiB14478

procfs.hH A D11-Feb-20221.4 KiB5614

prof.hH A D14-Jun-20171.6 KiB7535

prof_attr.hH A D03-Aug-20142.7 KiB10551

project.hH A D11-Feb-20222.4 KiB7538

pthread.hH A D23-Jul-202415.5 KiB391253

pw.hH A D14-Jun-20171.2 KiB4412

pwd.hH A D14-Jun-20175.8 KiB17885

rctl.hH A D24-Nov-20161.8 KiB6227

re_comp.hH A D03-Aug-20141.2 KiB4612

regex.hH A D06-Jun-20175.7 KiB17288

regexp.hH A D20-Jun-20179.4 KiB570444

resolv.hH A D02-Jul-201716.8 KiB446283

rje.hH A D14-Jun-20173.4 KiB11879

rtld_db.hH A D03-Aug-20145.3 KiB195102

sac.hH A D14-Jun-20174.4 KiB15347

sched.hH A D03-Aug-20142.1 KiB7331

schedctl.hH A D03-Aug-20141.6 KiB6322

search.hH A D14-Jun-20172.5 KiB9040

secdb.hH A D19-Aug-20103 KiB10462

semaphore.hH A D23-Jul-20243 KiB9946

setjmp.hH A D11-Dec-20241.7 KiB6924

sgtty.hH A D14-Jun-20172.8 KiB13683

shadow.hH A D02-Jul-20173.2 KiB10146

siginfo.hH A D14-Jun-20171.6 KiB6325

signal.hH A D12-Aug-20175.4 KiB176109

spawn.hH A D19-Jul-20245.9 KiB218133

stack_unwind.hH A D02-Jul-20178.2 KiB297118

stdalign.hH A D25-Jan-2023556 224

stdarg.hH A D03-Aug-20141.8 KiB598

stdbit.hH A D12-Oct-2024781 284

stdbool.hH A D18-Aug-20091,017 334

stddef.hH A D14-Jun-20172.2 KiB8026

stdint.hH A D07-Aug-20181.3 KiB469

stdio.hH A D16-Mar-202510.7 KiB392260

stdio_ext.hH A D11-Feb-20222.7 KiB8728

stdio_impl.hH A D24-Nov-20162 KiB7637

stdio_tag.hH A D24-Nov-20161.3 KiB4817

stdlib.hH A D07-May-202511 KiB362259

stdnoreturn.hH A D29-Mar-2016790 3913

storclass.hH A D14-Jun-20172.3 KiB7837

string.hH A D07-Apr-20245.8 KiB200134

strings.hH A D03-Aug-20142.4 KiB7932

stropts.hH A D12-Jul-20252 KiB7122

syms.hH A D02-Jul-20175.3 KiB229127

synch.hH A D02-Jul-20177.1 KiB225123

sysexits.hH A D14-Jun-20174.8 KiB12928

syslog.hH A D14-Jun-20171.4 KiB5319

tar.hH A D14-Jun-20172.6 KiB10049

termio.hH A D14-Jun-2017987 324

termios.hH A D14-Jun-2017991 324

tgmath.hH A D04-Feb-20144.2 KiB172127

thread.hH A D08-Oct-20183.9 KiB13356

thread_db.hH A D02-Jul-201717.3 KiB691355

threads.hH A D18-Apr-20263 KiB11474

time.hH A D12-Jan-202510.4 KiB324181

tiuser.hH A D14-Jun-20171.4 KiB5517

tzfile.hH A D22-Feb-20258.3 KiB27490

uchar.hH A D02-Mar-20252.1 KiB7536

ucontext.hH A D11-Dec-20243.1 KiB9845

ucred.hH A D03-Aug-20142.1 KiB7730

ulimit.hH A D14-Jun-20171.1 KiB4511

unistd.hH A D11-Dec-202426 KiB723538

upanic.hH A D23-Oct-2020784 3712

user_attr.hH A D30-Sep-20204.5 KiB14688

userdefs.hH A D30-Sep-20204.6 KiB17890

ustat.hH A D14-Jun-20171.2 KiB4612

utime.hH A D14-Jun-20171.2 KiB4711

utmp.hH A D02-Jul-20174.9 KiB16981

utmpx.hH A D14-Jun-20174.8 KiB15281

valtools.hH A D14-Jun-20171.6 KiB7440

values.hH A D14-Jun-20175.1 KiB14360

varargs.hH A D14-Jun-20172.2 KiB7924

wait.hH A D14-Jun-20171.3 KiB5016

wchar.hH A D27-Dec-20245.6 KiB207156

wchar_impl.hH A D11-Feb-20221.2 KiB5220

wctype.hH A D28-Mar-20154.5 KiB16396

widec.hH A D14-Jun-20173.9 KiB12769

wordexp.hH A D03-Aug-20142.4 KiB8133

xlocale.hH A D07-May-20254.4 KiB13174

xti.hH A D02-Jul-201716.9 KiB541286

xti_inet.hH A D14-Jun-20171,013 324

zone.hH A D23-Sep-20092.4 KiB7833

README.cplusplus.md

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