将"this"指针强制转换为另一种类型不违反严格锯齿?

Casting the "this" pointer to another type does not violate strict aliasing?

本文关键字:另一种 指针 this 转换 类型      更新时间:2023-10-16

所以如果我做这样的事情:

#include <ios>
using std::forward;
template<class T>
struct pod_version final{
    private:
        alignas(T) uint8_t m_data[sizeof(T)];
    public:
        pod_version()=default;
        pod_version(const pod_version&)=default;
        pod_version(pod_version&&)=default;
        ~pod_version()=default;
        pod_version& operator=(const pod_version&)=default;
        pod_version& operator=(pod_version&&)=default;
        template<class...V>void construct(V&&...v){
            new (m_data) T(forward<V>(v)...);
        }
        void destroy(){
            reinterpret_cast<T*>(m_data)->~T(); // g++: warning typed punned blah im allowed to break ur code LOL
            reinterpret_cast<T*>(this)->~T(); // g++: :D
        }
};
int main(){
    pod_version<int> x;
    x.construct(5);
    x.destroy();
    return 0;
}

注意:"m_data"和"this"应该指向同一个地方...

海湾合作委员会 4.8.1

使用 char ,而不是 uint8_t

类型双关规则有一个特殊情况,分别是charsigned charunsigned char,并且只有这些类型。 uint8_t不需要指其中之一。

请注意,这个pod_version类的整个概念是可疑的。 您正在对无效的类型强制使用简单的复制语义。 代码将尝试在未初始化的内存或对象的二进制图像上调用析构函数。 两者都会导致未定义的行为。

您的编译器正确抱怨m_data的强制转换,因为m_data不是char*类型而是int8_t*类型。严格的混叠规则不允许类型双关语,除了char*unsigned char*signed char*之外的任何内容。

可能

,编译器无法弄清楚通过将pod_version<T>*转换为T*可能暗示某些邪恶的东西。毕竟,这些都是复杂的类型,编译器不知道您将访问T的哪些成员,它可能是int8_t成员,在这种情况下,强制转换将完全没问题。毕竟,仅当您访问与不同基本类型的相同内存位置时,才会调用未定义的行为,而不是在更改指针类型时调用。

在任何情况下,您都通过编写强制转换来明确地告诉编译器"我知道我在做什么",因此任何健全性检查都是完全可选的。

标准不需要警告。实现可能会出于他们认为合适的任何原因警告您,或者根本不警告您。

值得一提的是,gcc 4.8.2 使用 -Wall 静默编译您的代码。编辑:不,它没有。