P0137引入了函数模板, std::launder并在有关联合,生命周期和指针的部分中对标准进行了许多更改.
这篇论文解决了什么问题?我必须注意哪些语言的变化?我们在做什么launder?
当我使用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*意味着它实际上不能为任何类型别名吗?
AFAIK,在三种情况下可以使用别名
在阅读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) 我正在阅读 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)