lundi 29 avril 2019

Pointers to static variables must respect canonical form?

Assuming I have the following example:

struct Dummy {
    uint64_t m{0llu};

    template < class T > static uint64_t UniqueID() noexcept {
        static const uint64_t uid = 0xBEA57;
        return reinterpret_cast< uint64_t >(&uid);
    }
    template < class T > static uint64_t BuildID() noexcept {
        static const uint64_t id = UniqueID< T >()
               // dummy bits for the sake of example (whole last byte is used)
               | (1llu << 60llu) | (1llu << 61llu) | (1llu << 63llu);
        return id;
    }
    // Copy bits 48 through 55 over to bits 56 through 63 to keep canonical form.
    uint64_t GetUID() const noexcept {
        return ((m & ~(0xFFllu << 56llu)) | ((m & (0xFFllu << 48llu)) << 8llu));
    }
    uint64_t GetPayload() const noexcept {
        return *reinterpret_cast< uint64_t * >(GetUID());
    }
};

template < class T > inline Dummy DummyID() noexcept {
    return Dummy{Dummy::BuildID< T >()};
}

Knowing very well that the resulting pointer is an address to a static variable in the program.

When I call GetUID() do I need to make sure that bit 47 is repeated till bit 63?

Or I can just AND with a mask of the lower 48 bits and ignore this rule.

I was unable to find any information about this. And I assume that those 16 bits are likely to always be 0.

This example is strictly limited to x86_64 architecture (x32).

Aucun commentaire:

Enregistrer un commentaire