2411d,右值与移动

原文

概述

添加语言内部__rvalue(Expression)函数,指示对匹配函数参数,按右值对待.这在用非引用语义调用函数时启用移动语义.

移动语义运行时和资源效率可取的,因为可移动资源新对象,而不是复制然后析构.其他语言(如C++)有流行移动语义.

先前的工作

C++移动语义这里
RustC++移动语义对比这里
C++语义有害(Rust更好)这里

描述

语法

RvalueExpression是个附加PrimaryExpression:

cpp 复制代码
RvalueExpression:
    __rvalue ( AssignExpression )

重载

如果同时有引用非引用参数重载,则偏爱匹配右值非引用参数,而偏爱左值引用参数匹配.RvalueExpression最好与非引用参数匹配.

右值参数匹配参数语义

调用函数拥有对待右值参数.因此,如果左值与右值参数匹配,则会给函数传递左值副本.然后,在函数结束时该函数对(如果有)参数调用析构器.

不会复制右值参数,因为按唯一假设它,且在函数结束时也会析构它.编译器会自动函数体附加析构.

函数无法知道其参数源右值还是左值的副本.

即在函数返回时,__rvalue(左值式)参数析构式.不能继续使用左值式.在传递给函数后,编译器并不总是可检测到使用,即对象的析构器必须按其初值或至少是良性值,重置对象的内容.

cpp 复制代码
struct S
{
    ubyte* p;
    ~this()
    {
      free(p);
      //在此添加:`'p=null;'`
    }
}
void aggh(S s)
{
}
void oops()
{
    S s;
    s.p = cast(ubyte*)malloc(10);
    aggh(__rvalue(s));
    free(s.p); //错误,两次释放`s.p`
}

__rvalue移动赋值

cpp 复制代码
struct S
{
    ubyte* p;
    ~this()
    {
      free(p);
      p = null;
    }
    void opAssign(S s)
    {
        this.p = s.p;
        s.p = null;
    }
}
void oops()
{
    S s;
    s.p = cast(ubyte*)malloc(10);
    S t;
    t = __rvalue(s);
}

__rvalue移动构造

cpp 复制代码
struct S
{
    ubyte* p;
    ~this()
    {
      free(p);
      p = null;
    }
    this(S s)
    {
        this.p = s.p;
        s.p = null;
    }
}
void oops()
{
    S s;
    S t = __rvalue(s);
}
相关推荐
fqbqrr5 个月前
2407d,D2024三月会议
d
fqbqrr8 个月前
2403d,d的com哪里错了
d
fqbqrr10 个月前
2402d,d的变参
d
fqbqrr10 个月前
2401d,ddip1027如何支持sql
d
fqbqrr10 个月前
2401d,讨论d串滑动参数
d
fqbqrr1 年前
2312d,D语言单元测试等
d
fqbqrr1 年前
2312d,d语言作为胶水,用C++调用rust
c++·rust·d
fqbqrr1 年前
2312d,把alloca注入调用者域
d
fqbqrr1 年前
2312d,d语言来绑定C++和rust
c++·rust·d