相关疑难解决方法(0)

std :: launder的目的是什么?

P0137引入了函数模板, std::launder并在有关联合,生命周期和指针的部分中对标准进行了许多更改.

这篇论文解决了什么问题?我必须注意哪些语言的变化?我们在做什么launder

c++ memory c++-faq c++17 stdlaunder

223
推荐指数
3
解决办法
2万
查看次数

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

当我使用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
查看次数

如何推理类似 malloc 的函数的严格别名

AFAIK,在三种情况下可以使用别名

  1. 仅限定符或符号不同的类型可以相互别名。
  2. 结构或联合类型可以为其中包含的类型指定别名。
  3. 将 T* 转换为 char* 就可以了。(不允许相反)

在阅读John Regehrs 博客文章中的简单示例时,这些是有意义的,但我不确定如何推理较大示例(例如类似 malloc 的内存安排)的别名正确性。

我正在阅读Per Vognsens 重新实现Sean Barrets弹性缓冲区。它使用类似 malloc 的模式,其中缓冲区在其前面具有关联的元数据。

typedef struct BufHdr {
    size_t len;
    size_t cap;
    char buf[];
} BufHdr;
Run Code Online (Sandbox Code Playgroud)

通过从指针减去偏移量来访问元数据b

#define buf__hdr(b) ((BufHdr *)((char *)(b) - offsetof(BufHdr, buf)))
Run Code Online (Sandbox Code Playgroud)

这是原始buf__grow函数的一个稍微简化的版本,它扩展了缓冲区并将 buf 作为void*.

void *buf__grow(const void *buf, size_t new_size) { 
     // ...  
     BufHdr *new_hdr;  // (1)
     if (buf) {
         new_hdr = xrealloc(buf__hdr(buf), new_size);
     } else {
         new_hdr = xmalloc(new_size); …
Run Code Online (Sandbox Code Playgroud)

c strict-aliasing

5
推荐指数
1
解决办法
941
查看次数

为什么这里需要 std::launder ?

我正在阅读 cppreference ,在std::aligned_storage的示例中有一个向量/数组类的示例:

template<class T, std::size_t N>
class static_vector
{
    // properly aligned uninitialized storage for N T's
    typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N];
    // IF you want to see possible implementation of aligned storage see link.
    // It's very simple and small, it's just a buffer
    
    std::size_t m_size = 0;
 
public:
    // Create an object in aligned storage
    template<typename ...Args> void emplace_back(Args&&... args) 
    {
        if( m_size >= N ) // possible error handling
            throw std::bad_alloc{};
 
        // construct value in memory …
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing undefined-behavior stdlaunder

5
推荐指数
1
解决办法
954
查看次数