自 C++20 以来是否允许对分配的存储进行指针运算? [英] Is pointer arithmetic on allocated storage allowed since C++20?

查看:19
本文介绍了自 C++20 以来是否允许对分配的存储进行指针运算?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C++20 标准中,数组类型是隐式生命周期类型.

In the C++20 standard, it is said that array types are implicit lifetime type.

这是否意味着可以隐式创建非隐式生命周期类型的数组?这种数组的隐式创建不会导致数组元素的创建?

Does it mean that an array to a non implicit lifetime type can be implicitly created? The implicit creation of such an array would not cause creation of the array's elements?

考虑这种情况:

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (which object?)
std::string * sptr = std::launder(static_cast<std::string*>(ptr));
//pointer arithmetic on not created array elements well defined?
new (sptr+1) std::string("second element");

从 C++20 开始,这段代码就不再是 UB 了吗?

Is this code not UB any more since C++20?

也许这种方式更好?

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (actually not necessary)
std::string (* sptr)[10] = std::launder(static_cast<std::string(*)[10]>(ptr));
//pointer arithmetic on an array is well defined
new (*sptr+1) std::string("second element");


TC 回答 + 评论结论:

  1. 未创建数组元素但已创建数组
  2. 在第一个示例中使用 launder 导致 UB,并且是在第二个示例中不需要.
  1. Array elements are not created but the array is created
  2. The use of launder in the first example cause UB, and is not necessary in the second example.

正确的代码是:

    //implicit creation of an array of std::string 
    //but not the std::string elements:
    void * ptr = operator new(sizeof (std::string) * 10);
    //the pointer already points to the implicitly created object
    //so casting is enough 
    std::string (* sptr)[10] = static_cast<std::string(*)[10]>(ptr);
    //pointer arithmetic on an array is well defined
    new (*sptr+1) std::string("second element");

推荐答案

这是否意味着可以隐式创建非隐式生命周期类型的数组?

Does it means that an array to a non implicit lifetime type can be implicitly created?

是的.

这种数组的隐式创建不会导致数组元素的创建?

The implicit creation of such an array would not cause creation of the array's elements?

是的.

这就是 std::vector 可以在普通 C++ 中实现的原因.

This is what makes std::vector implementable in ordinary C++.

这篇关于自 C++20 以来是否允许对分配的存储进行指针运算?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆