d放松不变3

:但是仅使rc计数结构可变的问题是什么?
这样,不会遇到绕过不变/常系统,只是增加计数器或元数据问题.
注意:rc构的有效负载,如果需要,可是不变的.

理论上,这是我认为的正确方法.但是,它确实妨碍了可用性.如,你不能再写:

auto myFunc(in RC!Data data) { ... }

因为RC!...必须始终保持可变.必须这样了:

auto myFunc(RC!(const(Data)) data) { ... }

一些不错隐式转换也不再工作.
如,RC!Data不会隐式转换为RC!(const(Data)),
而使用GC处理数据时,可隐式转换Data*const(Data)*.这不对称性使得元编程更难与RC一起工作.
一旦有嵌套结构,事情更糟,如:

struct SubData {...}
struct S {
    RC!SubData data;
}

现在不能传递S给需要的东西,因为传递性会强制RC!SubData变为常(RC!SubData),这会破坏引用计数机制.
只要数据结构的子部分中有RC!xxx,它就会用可变来"反向感染"整个数据结构,不能再在结构的包含部分使用,因为它会破坏RC.
除非有像__mutable这样的特例,否则一旦子部分涉及RC,就必须从数据结构中完全抛弃常/不变了.

如果简单定义@system变量为"不能从@safe代码中使用",则这不明显.如果定义为"可覆盖类型系统",则是显而易见的.
唯一问题是这是否是语言设计?这当然很容易解释:
问:“什么是@system变量?”
A:“只要来自@system代码,可用它做的变量.”
问:“目的?”
A:“做普通变量无法做到,及编译器无法自行判断时标记普通变量为危险.”

如果愿意放弃pure,可让RC不变一起工作:
个人而言,我宁愿放弃pure(其中已有漏洞),也不愿给不变(目前无漏洞)添加漏洞.

RC!(常 T)更好.
不能用别名 本吗?
即在Rc结构中这样:

alias this = asQualified;

其中asQualified返回具有合适修饰符版本.

诚然,按字段用RC并不容易,但是否可禁止不变版本,来为初始实现忽略该问题?
始终可扩展RC结构来支持自身的不变/常限定符.
也许最好先实现受限版本?即只有可变rcs?

当然是的.阻碍了表现力,增加了附带复杂性.双输.
语言不应加额外语句就描述了我的意思.

这是我用来确定需要做什么才能使常RC类型无用(并希望是安全的)的测试代码.

void main() {
    auto r1 = /+const+/ Reference(2);
    const r2 = r1;
    const r3 = Reference(2);
    const(Reference) r4 = Reference(2);
    //auto r5 = cast(const)r1;
    auto r6 = cast(void*)&r1;
    auto r7 = cast(const)&r1;
}

struct Reference {
    int x;

@safe:

    this(int value) {
        this.x = value;
    }

    this(ref Reference other) {
        this.x = other.x;
    }


    ~this() {
        this.x = 0;
        writeln("析构器");
    }

    void opAssign(ref Reference other) {
        __ctor(other);
    }

    void opAssign(Reference other) {
        __ctor(other);
    }

    // bool isNull() { ... }

    @disable this(int value) const;

    //@disable this(ref Reference other) const;
    @disable this(ref const Reference other) const;
    @disable this(this);

    //@disable ~this() const;

    @disable void opAssign(ref Reference other) const;
    @disable void opAssign(Reference other) const;

    @disable auto opCast(T)();
}

:当然是的.阻碍了表现力,增加了附带复杂性.双输.
错误.允许做你想做不强迫不想做的时,简单就是好的.如果你说的是真的,则D应该用曾经建议的每一个内置属性类型限定符,因为缺少它们会"妨碍表达".

DIP1035的用例,一般是使用__metadata|__mutable的严格子集.同意只能从@system代码中访问__metadata变量.因此,实现__metadata,基本上可免费得到DIP1035.我建议,简单用DIP1035@system来包含这两个想法.

DIP1035目的是强制不安全对待按不安全的方式使用的变量.如果要确定合并@system__metadata是否是好主意,首先要提出用例来证明可能的目的冲突,如下所示.
需要展示因为不安全方式的@system变量,可能导致按不同方式危险地使用它,现在,它是不变的了.
对我来说,这很艰巨.如果不能提供示例,凭什么说这两个功能不能结合?
我的主要观点是,可变性正是标记变量@system的原因.对初化为不安全值并因此推导@system的全局数据,我甚至不知道他们的用途.对我来说它们是错误.

我实现了shared_ptr/rc_ptr.这里

SharedPtr!(const int) sp = SharedPtr!int.make(42);

const SharedPtr!(const int) csp1 = sp;  //OK
const SharedPtr!(int) csp2 = sp;  //OK

sp = csp1;   //ERROR
sp = csp2;   //ERROR

//RcPtr is same.

D中引用计数指针有问题:
D中的RAII很糟糕:未实现移动ctor,重载复制ctor有时会导致dmd崩溃,GC切片不能调用复制ctor,dtor栈元组/值序列opCast,emplace的交互不良…
简单的ref计数指针也有该问题:

Rc!(const int) rc1 = Rc!(int).make(42);
Rc!(const int) rc2 = Rc!(immutable int).make(42);

Rc!(const int)的原子计数吗?

你的提议并不简单.
你的提议迫使我做不想做,而禁止我想做的.我不想要它.
你的提议不符合自己的标准.
很明显,你认为简单性和表达性都是语言中属性数量的单调函数.如果是这样,应将@safepure@nogcnothrow混为一谈,那样"更简单".这是荒谬的!

__metadata更多好处加更多限制.几乎没有D程序员必须直接使用它.
不,我建议你阅读DIP1035并找到__metadata未涵盖的方面.
不能简单地把@system__metadata混为一谈
所以所有潜在危险的东西都一样吗?也可在此时完全关闭"@system"代码中的检查类型和边界.多么荒谬推理.
即使可变性是问题,也不应简单地隐式/偶然绕过"常",即使在"@system"代码中也是如此.
该提议问题:
@system不表明"这是可变的",这是非常不直观的语言规则.你可字面上声明@系统 不变,就会被忽略.
@system变量在低级代码中相当常见.显式__mutable更专业,并在应用上受到限制.扩展@system来包含该更狭窄用例无意义,因为大多数@system用户不想要它.
可从初化程序中推导@system.如果const/immutable只是从变量声明中脱离出来,则非常令人困惑,尤其是如果它不经常时.
通过把__metadata@system混为一谈,编译器似乎在使用隐含,不安全的和不必要的类型双关语.初化时,不变现有值中去掉了传递性.可能还有无法编译@system t=foo(),这种设计,因为你不能把foo()不变结果赋值给可变的t,但这同样无意义.
模板代码可能有基于参数可变性而不同的逻辑(如,从A到B实例,复制所有可变字段值).

对不同模板参数,模板内的变量并不总是相同方式推导为"@system".现在突然,有时会完全不安全,完全隐含类型双关语,甚至无法从外部分辨出来.如果"幸运",代码可能无法编译,因为你无法将T v=init();赋值回T w等内容.
内存安全可能取决于保持值的@system字段,因此拥有不变@system字段很有用.
可有相同,其中一些是静态类型可变和不可变实例.如果类型有@system字段,该提案阻止不变实例存储在只读数据段中.
@system值与基于不变的其他优化同样工作.(除非@system__metadata任意混为一谈.)不应在快速代码和@safe检查的健壮性间做出选择.

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