C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Only reason I don't use std::array

From: Tom Honermann <tom_at_[hidden]>
Date: Thu, 17 Aug 2023 11:53:48 -0400
On 8/17/23 11:40 AM, Frederick Virchanza Gotham via Std-Proposals wrote:
> On Thu, Aug 17, 2023 at 12:41 PM Ville Voutilainen via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>> Well, yeah - the actual problem is that nothing prevents the
>> implementation from putting a T[N+IMPL_DEFINED_CONSTANT] there.
>
> I would feel safe using the following code on anything from an Arduino
> microcontroller to an x86_64 Ubuntu PC. I don't anticipate a problem
> with it, especially because of the two static_assert's. Do you think
> it could possibly malfunction on even the strangest of platforms?

The code has undefined behavior since no object of std::array<T,len>
actually exists at the address returned by pretend_is_std_array(). While
the code might exhibit the behavior you want today, there is no
guarantee that a future compiler upgrade won't include optimizer changes
that cause it to behave differently. Violating the C++ object model is
not something I would recommend.

Tom.

>
> GodBolt: https://godbolt.org/z/c14YjqPvK
>
> #include <cstddef> // size_t
> #include <array> // array
> #include <type_traits> // is_const, remove_const
>
> template< typename T, std::size_t len > requires (!std::is_const_v<T>)
> std::array<T,len> &pretend_is_std_array( T (&arg)[len] )
> {
> static_assert( sizeof(std::array<T,len>) == sizeof(T[len]) );
>
> return *static_cast< std::array<T,len>* >(static_cast<void*>(&arg));
> }
>
> template< typename T, std::size_t len > requires std::is_const_v<T>
> std::array< std::remove_const_t<T>, len > const &pretend_is_std_array(
> T (&arg)[len] )
> {
> static_assert( sizeof(std::array< std::remove_const_t<T>, len >)
> == sizeof(T[len]) );
>
> return *static_cast< std::array< std::remove_const_t<T>, len >
> const * >(static_cast<void const*>(&arg));
> }
>
> void SomeFunc ( std::array<int,16> & ) {}
> void SomeFuncC( std::array<int,16> const & ) {}
>
> int main(void)
> {
> int monkey[16u] = {};
> int const donkey[16u] = {};
>
> SomeFunc ( pretend_is_std_array(monkey) );
> SomeFuncC( pretend_is_std_array(donkey) );
> }

Received on 2023-08-17 15:53:50