d放松不变4

如果@system__metadata是单独的注解,你会得到:@system规则__metadata规则.
变量是@system原因很多,因为它只是收集了不安全的来源.__metadata是考虑添加语言中的新的此类源.
因为DIP1035并不改变变量类型.
编译器仍跟踪所有这些,并使其作为注解部分,来更易理解.
新手在很长一段时间内都不必学习__metadata@system变量.可能某时遇到@system变量,最后,更少数D程序员需要非常关注__metadata规则.

这里,"不安全类型"在DIP中详细说明了,有特定意思.即使是不安全类型,一般可从@safe代码中使用.

我同意实际工作生命期语义应比在不变结构中隐藏引用计数更高优先级.
:不变与rc.
我认为该问题的方法应归结为以下之一:
-接受不变表明不变,仅在强制执行该从基于UB(未定义行为)的规范中继承有效编译器优化限制真正有意义就使用它.禁止使用不变RC.不变总是可放在只读内存中,这是CTFE访问不变值的简单故事.
-接受"不变"结构中有专门用于低级目的可变部分,区分"不变"和"共享 不变",明确指定基于非确定性语义有效编译器优化.不变RC是个问题.根据特定类型决定是否放"不变"值进只读内存,CTFE访问不变值更复杂.

这不是应用限定符用户定义类型的唯一问题.内置切片指针类型,相对用户定义类型,与限定符有神奇交互作用.

:带@系统字段的聚集不安全类型.
目的是防止@safe代码中,对@system字段类型的空初化等.仍可在不用@trusted就访问结构非@system字段.

不安全类型”,不表明不能在@safe代码中使用它.如,指针不安全类型,可在@safe代码中安全使用指针."不安全类型"即,在@safe代码中,仅在编译器知道不会导致损坏内存使用它.

是的.
但如果编译器允许RC变为,并禁止RC,那就糟了.
那就是我上面的测试代码干的,它会尽量避免用const.这是解决更大问题的方法.

不变生命期语义无关.只是说不会修改这段内存.无论如何,真正问题在于.可变和不变都自动转为.

:这似乎是为了拥有适当的安全可变RC结构,需要纠正特例和错误.如果需要,应可禁止隐式转换为常 构.
对的.只需编写RC!T复制构造器来请求可变源和目标对象,编译器将拒绝复制const(RC!T).(当然,也可常 引用.)
:关于使用常 rc,我认为如果禁止取有效负载地址或子元素,可受限访问负载.也许不是从rc结构返回有效负载,而是包装到从负载访问字段时避免取地址的包装器中.
可传递负载的"域引用"给回调限制访问,如下:
这里

import std;

void main()
{
    int j = 2;
    int k = 3;
    const r3 = Counted!int(&j);
    const(Counted!int) r4 = Counted!int(&k);
}

@safe struct Counted(T)
{
    private T* subject;
    private size_t* counter;

    this(T* subject)
    {
        this.counter = new size_t;
        this.subject = subject;
        *this.counter = 1;
    }

    this(ref T subject) const @disable;
    this(T* subject) const @disable;

    this(ref Counted!T counted)
    {
        this.subject = counted.subject;
        this.counter = counted.counter;
        ++(*this.counter);
    }

    this(ref Counted!(const T) counted) const @disable;
    this(ref const Counted!T counted) const @disable;
    this(ref Counted!T counted) const @disable;

    this(this) @disable;

    ~this()
    {
        (*this.counter)--;

        if ((*this.counter) == 0)
        {
            writeln("释放:",*this.subject);
            this.counter = null;
        }
    }

    // ~this() const @disable; 很明显另一个漏洞或未图表区域.

    void opAssign(ref Counted!T counted)
    {
        --(*this.counter);
        this.subject = counted.subject;
        this.counter = counted.counter;
        ++(*this.counter);
    }

    void opAssign(Counted!T counted)
    {
        this = counted;
    }

    void opAssign(ref const(Counted!T) counted) const @disable;
    void opAssign(const(Counted!T) counted) const @disable;
    void opAssign(Counted!(const T) counted) const @disable;
    void opAssign(ref Counted!(const T) counted) const @disable;
    void opAssign(ref Counted!T counted) const @disable;
    void opAssign(Counted!T counted) const @disable;

    void opCast(T)() @disable;
}

没问题.创建且销毁了Counted!int的两个实例.没有泄露或悬空引用.如果复制构造附加实例,如

auto r5 = r4;

编译器正确的拒绝了.
当然,它只是因为编译器插入的析构器忽略了,这有点可疑,但这是无害的.
安全引用计数

posted @   zjh6  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示