P0137引入了函数模板, std::launder并在有关联合,生命周期和指针的部分中对标准进行了许多更改.
这篇论文解决了什么问题?我必须注意哪些语言的变化?我们在做什么launder?
(参考这个问题和答案.)
在C++ 17标准之前,[basic.compound]/3中包含以下句子:
如果类型T的对象位于地址A,则类型为cv T*的指针(其值为地址A)被称为指向该对象,而不管该值是如何获得的.
但是自从C++ 17以来,这句话已被删除.
例如,我相信这句话使这个示例代码定义,并且从C++ 17开始这是未定义的行为:
alignas(int) unsigned char buffer[2*sizeof(int)];
auto p1=new(buffer) int{};
auto p2=new(p1+1) int{};
*(p1+1)=10;
Run Code Online (Sandbox Code Playgroud)
在C++ 17之前,p1+1保持地址*p2并具有正确的类型,因此*(p1+1)是指向*p2.在C++中,17 p1+1是一个指向前端的指针,所以它不是指向对象的指针,我相信它不是可以解除引用的.
对标准权的这种修改的解释是否还有其他规则来补偿所引用的句子的删除?
我们来考虑这个示例代码:
struct sso
{
union {
struct {
char* ptr;
char size_r[8];
} large_str;
char short_str[16];
};
const char* get_tag_ptr() const {
return short_str+15;
}
};
Run Code Online (Sandbox Code Playgroud)
在[basic.expr]中指定只要结果指向数组的另一个元素(或超过对象的末尾或最后一个元素),就允许指针运算.尽管如此,如果数组是联合的非活动成员,则在本节中未指定会发生什么.我相信这不是问题short_str+15,永远不是UB.这样对吗?
以下问题清楚地表明了我的意图