C++ 编译时检查指针内存布局:constexpr中的联合方法失败

C++ 编译时检查指针内存布局:constexpr中的联合方法失败,c++,c++17,constexpr,unions,reinterpret-cast,C++,C++17,Constexpr,Unions,Reinterpret Cast,考虑以下代码: // Preamble #include <limits> #include <iostream> #include <type_traits> // Gives an unsigned int of the given size in bytes, if it exists template <std::size_t N> struct uint_of_sizeof { using type = std::conditi

考虑以下代码:

// Preamble
#include <limits>
#include <iostream>
#include <type_traits>

// Gives an unsigned int of the given size in bytes, if it exists
template <std::size_t N>
struct uint_of_sizeof
{
    using type = std::conditional_t<
        N == sizeof(unsigned char),
        unsigned char,
        std::conditional_t<
            N == sizeof(unsigned short int),
            unsigned short int,
            std::conditional_t<
                N == sizeof(unsigned int),
                unsigned int,
                std::conditional_t<
                    N == sizeof(unsigned long long int),
                    unsigned long long int,
                    std::conditional_t<
                        N == sizeof(std::size_t),
                        std::size_t,
                        std::conditional_t<
                            N == sizeof(unsigned long int),
                            unsigned long int,
                            void
                        >
                    >
                >
            >
        >
    >;
};

// Allows to reinterpret pointer as an unsigned integral value
template <class T>
union pointer_converter
{
    using pointer_type = T*;
    using value_type = typename uint_of_sizeof<sizeof(pointer_type)>::type;
    pointer_type pointer;
    value_type value;
}; 

// Returns whether the pointer seems to have a normal layout
template <class T>
constexpr bool check_pointer_layout()
{
    // Initialization
    constexpr std::size_t alignment = alignof(T);
    pointer_converter<T> converter0{nullptr};
    pointer_converter<T> converter1{nullptr};
    std::ptrdiff_t difference = 0;
    bool ok = true;

    // Checks zero and first increment
    converter1.value = alignment;
    difference = converter1.pointer - converter0.pointer;
    ok = converter0.value == 0 && difference == 1;

    // Checks shifts
    while (ok && converter1.value < converter1.value << 1) {
        ok = converter1.pointer - converter0.pointer == difference;
        converter1.value <<= 1;
        difference <<= 1;
    }

    // Finalization
    return ok;
}

// Main function
int main(int argc, char* argv[])
{
    /*constexpr*/ bool is_classical_layout = check_pointer_layout<int>(); /* HERE */
    std::cout << is_classical_layout << std::endl;
    return 0;
}
//序言
#包括
#包括
#包括
//给出给定大小的无符号整数(以字节为单位,如果存在)
模板
大小为的结构
{
使用type=std::conditional\u t<
N==sizeof(无符号字符),
未签名字符,
std::有条件的<
N==sizeof(无符号短整型),
无符号短整型,
std::有条件的<
N==sizeof(无符号整数),
无符号整数,
std::有条件的<
N==sizeof(无符号长整型),
无符号长整型,
std::有条件的<
N==sizeof(标准::大小_t),
标准:尺寸,
std::有条件的<
N==sizeof(无符号长整型),
无符号长整型,
无效的
>
>
>
>
>
>;
};
//允许将指针重新解释为无符号整数值
模板
联合指针转换器
{
使用指针_type=T*;
使用值\u type=typename uint\u of\u sizeof::type;
指针\ U型指针;
值\类型值;
}; 
//返回指针是否具有正常布局
模板
constexpr bool check\u指针\u布局()
{
//初始化
constexpr std::size\u t alignment=alignof(t);
指针_转换器转换器0{nullptr};
指针_转换器转换器1{nullptr};
标准::ptrdiff_t差=0;
bool ok=true;
//检查零和第一个增量
converter1.value=对齐;
差异=converter1.pointer-converter0.pointer;
ok=converter0.value==0&&difference==1;
//检查班次

while(ok&&converter1.valueuintpttr\u t
?因为holy冒烟。正确的方法是读取实现定义的行为,并相应地执行
\ifdef