相关疑难解决方法(0)

新char实际上是否保证类类型的对齐内存?

通过new char[sizeof(T)]保证分配一个缓冲区来分配一个缓冲区,该内存是为该类型正确对齐的T,其中所有成员T都有其自然的,实现定义的对齐方式(也就是说,您没有使用该alignas关键字来修改它们的对齐方式).

我已经看到这个保证在这里得到了一些答案,但我并不完全清楚标准是如何达到这个保证的.5.3.4-10标准给出了基本要求:基本上new char[]必须与之对齐max_align_t.

我所缺少的是所说的位alignof(T)总是有效的对齐,最大值为max_align_t.我的意思是,这似乎是显而易见的,但结构的最终对齐必须至多max_align_t吗?即使点3.11-3表示可能支持扩展对齐,编译器可能自己决定一个类是一个过度对齐的类型?

c++ language-lawyer c++11

57
推荐指数
2
解决办法
2519
查看次数

这真的打破了严格别名规则吗?

当我使用g ++编译这个示例代码时,我收到此警告:

警告:解除引用类型惩罚指针将破坏严格别名规则 [-Wstrict-aliasing]

代码:

#include <iostream>

int main() 
{
   alignas(int) char data[sizeof(int)];
   int *myInt = new (data) int;
   *myInt = 34;

   std::cout << *reinterpret_cast<int*>(data);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,不是data别名int,因此将其强制转换为int不会违反严格的别名规则?或者我在这里遗漏了什么?

编辑:奇怪,当我这样定义时data:

alignas(int) char* data = new char[sizeof(int)];
Run Code Online (Sandbox Code Playgroud)

编译器警告消失了.堆栈分配是否与严格别名产生差异?事实上它是一个char[]而不是一个char*意味着它实际上不能为任何类型别名吗?

c++ strict-aliasing language-lawyer

31
推荐指数
1
解决办法
1965
查看次数

将char数组转换为对象指针 - 这是UB吗?

我最近看到像这样的类用于"按需"构造对象,而不必出于各种原因使用动态内存分配.

#include <cassert>

template<typename T>
class StaticObject
{
public:
    StaticObject() : constructed_(false)
    {
    }

    ~StaticObject()
    {
        if (constructed_)
            ((T*)object_)->~T();
    }

    void construct()
    {
        assert(!constructed_);

        new ((T*)object_) T;
        constructed_ = true;
    }

    T& operator*()
    {
        assert(constructed_);

        return *((T*)object_);
    }

    const T& operator*() const
    {
        assert(constructed_);

        return *((T*)object_);
    }

private:
    bool constructed_;
    alignas(alignof(T)) char object_[sizeof(T)];
};
Run Code Online (Sandbox Code Playgroud)

这段代码,即将正确对齐的char数组转换为对象指针,被C++ 14标准视为未定义的行为,还是完全没问题?

c++ pointers undefined-behavior c++14

7
推荐指数
2
解决办法
656
查看次数