Does reinterpret_casting include std :: aligned_storage * in T * if std :: write does not violate strict anti-aliasing rules?

The following example is from std :: aligned_storage page cppreference.com:

#include <iostream>
#include <type_traits>
#include <string>

template<class T, std::size_t N>
class static_vector
{
    // properly aligned uninitialized storage for N T's
    typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N];
    std::size_t m_size = 0;

public:
    // Create an object in aligned storage
    template<typename ...Args> void emplace_back(Args&&... args) 
    {
        if( m_size >= N ) // possible error handling
            throw std::bad_alloc{};
        new(data+m_size) T(std::forward<Args>(args)...);
        ++m_size;
    }

    // Access an object in aligned storage
    const T& operator[](std::size_t pos) const 
    {
        return *reinterpret_cast<const T*>(data+pos);
    }

    // Delete objects from aligned storage
    ~static_vector() 
    {
        for(std::size_t pos = 0; pos < m_size; ++pos) {
            reinterpret_cast<T*>(data+pos)->~T();
        }
    }
};

int main()
{
    static_vector<std::string, 10> v1;
    v1.emplace_back(5, '*');
    v1.emplace_back(10, '*');
    std::cout << v1[0] << '\n' << v1[1] << '\n';
}

In this example, it is operator[]simply reinterpret_cast std::aligned_storage*up to T*without std:launderand performs direct indirect access. However, according to this question , it looks like undefined, even if an object of type Thas ever been created.

So my question is: does the sample program really violate strict anti-aliasing rules? If this is not so, what happened to my understanding?

+1
source share
2 answers

ISO ++ Standard - . , - , . .

P0137 . [basic.compound] 3:

T A, cv T *, A, , , .

[expr.static.cast], 13:

A , A T, , , A.

reinterpret_cast<const T*>(data+pos) T, . , .

P0137 . [basic.compound] 3:

:

  • (, )

  • ...

[expr.static.cast], 13:

A , A T, . , a, b T ( cv-qualification), a, b. .

reinterpret_cast<const T*>(data+pos) - std::aligned_storage<...>::type, - lvalue, , lvalue const T. v1[0] std::aligned_storage<...>::type lvalue, undefined 11 [basic.lval] ( ):

glvalue, , undefined:

  • ,

  • cv- ,

  • , ( [conv.qual]) ,

  • , , ,

  • , , ,

  • , ( , ),

  • , (, cv-) ,

  • a char, unsigned char std:: byte type.

+1

. Lvalue const T T, .

, , ; ++ 14 (N4140) [basic.life]/7. , , , data+pos , -new. "" -new.

: reinterpret_cast<T *>(data+pos)? , [basic.life]/7.

, , ( - ), ", ". , , , T *, , std::aligned_storage, a T.

, . P0137, ++ 17, . std::launder, mjolnir, , .

, std::launder ++ 17. , , P0137 ++ 17 launder.

IMHO UB ++ 14, std::launder, , , -new. UB, std::vector ++ 14, .

0

Source: https://habr.com/ru/post/1691517/


All Articles