sandthorn
sandthorn

Reputation: 2870

If std::addressof is a readable version of &. What is a readable version of *&?

*&x

Using c++11, we can write as

* std::addressof(x)

However, is there more readable version of this expression?

constexpr uint64_t lil_endian = 0x65'6e'64'69'61'6e; 
    // a.k.a. Clockwise-Rotated Endian which allocates like
    // char[8] = { n,a,i,d,n,e,\0,\0 }

constexpr auto& arr = 
    reinterpret_cast<const std::array<char,8> &>
        (*std::addressof(lil_endian) );

int main()
{
    const auto str = std::string(arr.crbegin()+2, arr.crend() );

    std::cout << str << '\n'
              << str.size() << '\n' << '\n';
    for (const auto ch : str) {
        std::cout << ch << " : " << std::hex << (unsigned int) ch << '\n';
    }

}


endian
6

e : 65
n : 6e
d : 64
i : 69
a : 61
n : 6e

godbolt.org/g/9StHsE

wandbox.org/permlink/ZzQ38IlDficO5UOi

Upvotes: 1

Views: 324

Answers (3)

rustyx
rustyx

Reputation: 85481

It's unclear what you're trying to do and why you use constexpr.

But there are a couple of issues with your code:

  • reinterpret_cast is not allowed in a constant expression.

  • aliasing uint64_t with a std::array is not allowed.

You can, however, work around both of these by aliasing using a const char* in a non-constexpr context. So the following is legal:

#include <iostream>

constexpr uint64_t lil_endian = 0x65'6e'64'69'61'6e; 

int main()
{
    auto arr = reinterpret_cast<const char*>(&lil_endian);
    for (size_t i = 0; i < sizeof(lil_endian); ++i) {
        std::cout << arr[i] << " : " << std::hex << (unsigned int) arr[i] << '\n';
    }

}

Incidentally also the need for *& disappears.

DEMO

== EDIT ==

If you just need to get a hold of the size of the variable in a generic way, just use sizeof in a function template. For example:

#include <cstdio>
#include <cstdint>

constexpr uint64_t lil_endian = 0x65'6e'64'69'61'6e; 
constexpr uint32_t lil_endian32 = 0x65'6e'64'69;

template<typename T>
void printIt(const T& it)
{
    auto arr = reinterpret_cast<const char*>(&it);
    for (size_t i = 0; i < sizeof(it); ++i) {
        putchar(arr[i]);
    }
}

int main()
{
    printIt(lil_endian);
    printIt(lil_endian32);
}

DEMO

Upvotes: 1

Oliv
Oliv

Reputation: 18081

Vittorio Romeo give you the answer to the second question.

The first supposition is wrong: "Is addressof the readable version of &". addressof is used to get the address of an object even if its class type has an overloaded operator &.

Upvotes: 11

Vittorio Romeo
Vittorio Romeo

Reputation: 93364

* std::addressof(x)

However, is there more readable version of this expression?

x

Upvotes: 19

Related Questions