目前的标准草案(想必是C++17)是在[basic.化合物/4]中说的
注意:数组对象及其第一个元素不是指针-可互换的,即使它们有相同的地址。- end注意事项
因此,指向对象的指针不能是reinterpret_castd来获得其包围数组指针。
现在,有std::launder,[ptr.launder1]
template<class T> [[nodiscard]] constexpr T* launder(T* p) noexcept; 要求:p表示内存中一个字节的地址A。一个对象X在其生命周期内,其类型类似于T位于地址A。通过结果可以到达的所有字节存储字节都可以通过p访问(见下文)。
可达性的定义在[ptr.launder3]中
备注:每当核心常量表达式中可以使用其参数的值时,就可以在核心常量表达式中使用该函数的调用。存储字节可以通过指针值到达,指针值指向对象Y (如果它位于Y所占用的存储器内)、指针与Y可转换的对象(如果Y是数组元素,则指针可立即封装数组对象)。如果T是函数类型或cv,则程序格式不正确.
现在,乍一看,由于我强调的部分,std::launder似乎可以用于进行上述转换。
但。如果p指向数组的一个对象,根据这个定义,数组的字节是可以到达的(即使p不是指针-可转换为数组指针),就像清洗的结果一样。所以,这个定义似乎并没有提到这个问题。
那么,std::launder是否可以用于将对象指针转换为其封闭的数组指针?
发布于 2018-07-27 08:49:00
备注:任何非精神分裂症的编译器都可能很乐意接受这一点,就像它会接受C风格的转换或重新解释的转换一样,所以只想看看就不是一种选择。
但是IMHO,你的问题的答案是否定的。如果Y是数组元素,则所强调的立即包围数组对象是在注释段落中,而不是在需要的段落中。这意味着,只要“要求”部分得到尊重,其中的备注也适用。由于数组及其元素类型不是相似的类型,因此不能满足需求,不能使用std::launder。
以下是一般的(哲学?)口译。在K&R C时代(70年代),C是用来取代汇编语言的。因此,规则是:编译器必须服从程序员,前提是源代码可以被翻译。因此,没有严格的混叠规则和指针不再是一个具有附加算术规则的地址。这在C99和C++03中发生了很大变化(更不用说C++11 +了)。现在,程序员应该使用C++作为一种高级语言。这意味着指针只是允许访问给定类型的另一个对象的对象,数组及其元素类型是完全不同的类型。内存地址现在只不过是实现细节而已。因此,试图将指向数组的指针转换为指向其第一个元素的指针违背了语言的哲学,可能会在编译器的后期版本中咬死程序员。当然,由于兼容性的原因,现实生活中的编译器仍然接受它,但我们甚至不应该尝试在现代程序中使用它。
https://stackoverflow.com/questions/51552713
复制相似问题