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