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*意味着它实际上不能为任何类型别名吗?
什么情况下,reinterpret_cast荷兰国际集团一char*(或char[N])是不确定的行为,当它定义的行为?我应该用什么经验来回答这个问题?
正如我们从这个问题中学到的,以下是未定义的行为:
alignas(int) char data[sizeof(int)];
int *myInt = new (data) int; // OK
*myInt = 34; // OK
int i = *reinterpret_cast<int*>(data); // <== UB! have to use std::launder
Run Code Online (Sandbox Code Playgroud)
但是在什么时候我们可以reinterpret_cast在一个char数组上做一个并且它不是未定义的行为?以下是一些简单的例子:
不new,只是reinterpret_cast:
alignas(int) char data[sizeof(int)];
*reinterpret_cast<int*>(data) = 42; // is the first cast write UB?
int i = *reinterpret_cast<int*>(data); // how about a read?
*reinterpret_cast<int*>(data) = 4; // how about the second write?
int j …Run Code Online (Sandbox Code Playgroud)c++ undefined-behavior language-lawyer reinterpret-cast c++17
以下示例来自cppreference.com 的std::aligned_storage 页面:
#include <iostream>
#include <type_traits>
#include <string>
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];
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{};
new(data+m_size) T(std::forward<Args>(args)...);
++m_size;
}
// Access an object in aligned storage
const T& operator[](std::size_t pos) const
{
return *reinterpret_cast<const T*>(data+pos);
} …Run Code Online (Sandbox Code Playgroud)