2505d,d的一些疑问
:1
.函数声明
没有体
,因此无法检查函数体
.
没有体
的原型必须总是信任声明
.你必须简单地假设参
上有'域'
断定调用者
不会保存该参数
,且调用者也可依赖它;即,使用temp/stack
内存来分配参数.
是,当然,这就是dip1000
的工作原理
.
:2
.检查所有体
表明编译速度
会减慢很多.
:如果不想逃逸分析
,就不要写'域'
;关键是,为什么你需要把两个属性
写在一起,才能使自身是完全可选
的第一个属性
生效
需要'域'
来表示传递的指针
不会逃逸.需要'中'
来指示允许通过函数的中
逃逸.
:3
.当在函数调用流图
有循环时,推导属性
出现先有鸡还是先有蛋
的问题
我不关注.
F调用G调用H调用F
.
你不能推导f
的属性,因为它依赖f
.你不能推导g
的属性,因为它依赖依赖g
的f
.等等.要解决它,需要构造数据流方程
,然后通过迭代
和收敛
到唯一的解
来求解这些方程
.
这就是链接到gflow.d
中的代码
的作用.它在注释中.
可惜,构建和解决DFE
的速度很慢.因此优化
后的构建比未优化的构建
慢得多.因此使用简单的DFA
而不是DFA
来推导属性
,因为想要快速的非优化构建
.
:是不是;接收参
但没有显式声明'域'
的模板只是花时间试推导'域'
,因为该模板的调用者
可能依赖该属性推导
.
当然.
:是,但我仍不明白;如果你不想逃逸分析
,请不要编写'域'
.
是,然后你不能用域指针调用该函数
.
:如果你真写了它,你已显式地表明你确实想要逃逸分析
,所以它应该.
我看不出有任何理由需要第二个无关
属性来使第一个属性``正常工作
,你编写'域'
认为它会有效,然后因为不写(或忘记写)另一个属性
,你的代码现在就在骗你.
除非被你试阻止
的逃逸漏洞
咬伤,否则你不会知道它;使情况实际上比无用更糟糕,因为当你追踪你的漏洞
时,你看着属性
并继续找其他地方
.
'域'
应该在你编写它时工作.如果说写'域'
推导出另一个属性
,则不管怎样…,但这不好,即'域'
默默地闲着,并混淆或误导
作者.
当你编写它时,它确实有效.“第二个无关属性
”(我假设是"中"
属性)指示域'
指针是否返回.
没有'中'
属性表明无法编写以下代码
:
int* = foo(scope int* a) { return a; }//错误:`'A'`正在通过`中`逃逸!
scope int* p = ...;
scope int* q = foo(p);
好吧,则为什么'域'
需要’@safe'
?
不是.不过,它需要-dip1000
.
int* foo(scope int* q) { return q; }
./cc -c x.d -dip1000
x.d(1)
:错误:可能无法返回"q"
域参数.
int* foo(scope int* q) { return q; }^
:好吧,则为什么'域'
需要’@safe'
,它自身就是一个额外的属性
;要求有第二个
属性,才能使第一个
属性生效,价值不大.
当你编写'域'
时,'域'
就应该可工作.如果你不想域检查,请不要写'域'
?
因为在@系统
代码中,你可随心所欲.但是,要向调用者,表明它是'域'
,请在参数列表
中添加该属性
.要靠你来兑现该承诺
.
在一个设计合理
的程序中应该最小化@系统
.这就是默认转为安全
的原因.
1
.'域'
不是类型
的一部分.它是一个存储类
,而不是类型限定器
.唯一的类型限定器
是immutable,const,shared
和进出
.
在编译器
处理类型时普遍处理它们.除了借用检查器
外,制作一个新的指针类型
会是一项巨大的工作.
2
.在传递属性
方面拥有丰富的经验.因此,使用它们有很多阻力.看看所有对'nogc'
是传递的抱怨就知道了.就我个人而言,我发现'常'
是传递性
的,严重阻碍
了在dmd
源码中使用'常'
.
问题是它不适合访问者
模式.有几种情况丢弃了'常'
.
3
.我很清楚
,最好
,如果@活
是传递性的,那会更响亮
.我98%
确定,如果@活
是传递性
的,它将立即毫无用处,因为没人愿意让现有程序或库
通过借用检查器
.
Rust
花了巨大的努力来说服人们他们必须丢弃现有代码
并从头开始重新编码
才能使用借用检查器
.将不得不丢弃许多现有代码
.
制作完美的借用检查器
是制作实用的检查器
的敌人.
4
.使dip1000
变成传递性,在现有代码
中会不实用.
5
.dip1000
使得给多个
间接赋值域
指针是一个错误(因为域
不是类型限定器
).
6
.当一个@活
函数调用另一个函数
时,"域"
参数是借用
,非域参数
是转移物主
.
7
.因为DFA
,编译@活
函数的速度很慢.使其有传递性
将使整个程序编译速度
像Rust
一样慢.
:D自身已有3种不同类型
的指针:引用,指针,数组/切片
.
加上'this'
,lazy
,闭包,关联数组和类引用
.
它们是D最初设计的一部分,该语言围绕着他们成长起来
.
他们还使dip1000
的实现非常复杂
.
试在新的指针类型
中折叠是个巨大的变化
.
如果我要为D重新做一次,我会努力考虑丢弃
其中的一半.几年前,我试摆脱lazy
,但遭到了很多阻力.
微软
的管理C++
有用不同语法
区分的普通指针
和gc
指针.但在市场上失败了.
:不承认语言的缺点
,很多人必须一遍遍地说明.你还不承认.
我已多次承认了它,并说明了所提出的方法
有的问题(传递性,新的指针类型
).
Rust
是一个一切围绕着借用检查器
的单一语言
.这不适合多彩的D
语言.借用检查器
必须与语言的其余部分
相适应.
当然,即妥协.妥协
不表明它毫无用处
.
:还有''中 引用''
和''中''
的混乱,可写成''中 域''
和''域 中''
.
这是因为有'引用'
.考虑'引用 整*p'
.如何建模引用的域
和指针的域
?
:这两个人都有相同逃逸集,只是关系强度
不同.
强度
?
:这当然是D社区实现过的最糟糕的设计决定之一,所有相关方都感到非常遗憾!😃
它背后的概念运作良好
.问题是所有指针构造
的复杂性
,比如不可见
的使用'本'
引用.
:记住DIP1000
只理解不逃逸
,在返回值
或本指针
中逃逸
.
这足以避免栈的逃逸指针
.它相当扎实
.如果你不同意,请提交一个代码片
来说明它.
:不支持多个输出
,这严重限制了它的能力
.
它不会严重限制它.甚至Rust
手册也说这很少见.这是一个可重构掉
的小小的不便.