integral_constant: MPL interop: Avoid one function-local static object.

If the compiler does not optimize away the `pdata` function-local `static` object,
it ends up occupying space in the data section
and it is going to need a corresponding relocation entry
(just in case the module is not loaded at the desired address,
as is the case with ASLR in Windows Vista and later and in modern versions of Linux).

I admit that, for the current code,
both MSVC and GCC manage to optimize away `pdata` even if it is `static`.

But Boost should be an example of good coding
which can be applied even to more complicated source code,
e.g. to source code which calls `opaque_function (&pdata)`
(in which case, if `pdata` is static, both MSVC and GCC do emit an extra relocation).

And for other more complex cases, a function-local static-storage-duration object
costs even more (as compared to a function-local automatic-storage-duration object
given C++11 rules for "thread-safe" initialization of function-local `static`s.

And I wish to re-iterate that, in my opinion,
a good way to cast a pointer-to-one-type to a pointer-to-an-unrelated-type
is not by `reinterpret_cast` (which by the way makes `pdata` not needed any more),
but by using pointer to (possibly cv-qualified) `void` as an intermediary pointer type:

```
return static_cast <const Target *> (static_cast <const void *> (pointer_to_source))
```

or:

```
const void *const intermediary (pointer_to_source); // Not `static` for the general case.
return static_cast <const Target *> (intermediary);
```

Therefore, if the authors kindly agree, we can make this code an example for this style.
This commit is contained in:
Adder
2025-01-06 00:24:20 +02:00
committed by John Maddock
parent 0422aebeb8
commit ff0ae13c64

View File

@ -60,7 +60,7 @@ namespace boost{
operator const mpl::integral_c<T, val>& ()const
{
static const char data[sizeof(long)] = { 0 };
static const void* pdata = data;
const void* const pdata = data;
return *static_cast<const mpl::integral_c<T, val>*>(pdata);
}
BOOST_CONSTEXPR operator T()const { return val; }
@ -80,7 +80,7 @@ namespace boost{
operator const mpl::bool_<val>& ()const
{
static const char data[sizeof(long)] = { 0 };
static const void* pdata = data;
const void* const pdata = data;
return *static_cast<const mpl::bool_<val>*>(pdata);
}
BOOST_CONSTEXPR operator bool()const { return val; }