C++ Logo

std-discussion

Advanced search

Re: Is it valid use reinterpret_cast to form pointer to object?

From: Thiago Macieira <thiago_at_[hidden]>
Date: Mon, 31 Jul 2023 16:58:33 -0700
On Monday, 31 July 2023 16:33:42 PDT Thiago Macieira via Std-Discussion wrote:
> void process(Stream* stream) {
> std::unique_ptr<char[]> buffer = stream->read();
> if (buffer[0] == FOO)
> processFoo(reinterpret_cast<Foo*>(buffer.get()));
> else
> processBar(reinterpret_cast<Bar*>(buffer.get()));
> }
>
> But the standard also says that memcpy() is allowed to implicitly create
> objects, something this paper even reminds us of. Since any read() implies a
> memcpy() from some other storage, I argue that the object's lifetime was
> already started. This means the correct function here was std::launder().

And see my other reply: how do you prove that the read() → memcpy() didn't
create an object of type

union U
{
    char storage[std::max(sizeof(Foo), sizeof(Bar))];
    Foo foo;
    Bar bar;
};

That means reinterpret_cast is allowed here without UB.

The prototypical use of this is struct sockaddr, like in my own code at
https://github.com/qt/qtbase/blob/c6fce818db7e56f659ea88784d2f9278f9ce1436/
src/network/socket/qnativesocketengine_p.h#L77

inline QT_SOCKLEN_T setSockaddr(sockaddr *sa, const QHostAddress &addr,
quint16 port = 0)
{
    switch (addr.protocol()) {
    case QHostAddress::IPv4Protocol:
        return setSockaddr(reinterpret_cast<sockaddr_in *>(sa), addr, port);

    case QHostAddress::IPv6Protocol:
    case QHostAddress::AnyIPProtocol:
        return setSockaddr(reinterpret_cast<sockaddr_in6 *>(sa), addr, port);

This is allowed because those three types are members of
union qt_sockaddr {
    sockaddr a;
    sockaddr_in a4;
    sockaddr_in6 a6;
};
https://github.com/qt/qtbase/blob/c6fce818db7e56f659ea88784d2f9278f9ce1436/
src/network/socket/qnativesocketengine_p_p.h#L63-L67
-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel DCAI Cloud Engineering

Received on 2023-07-31 23:58:35