d懒参数问题
原文
当前懒参数
表明创建引用局部变量
的闭包
.允许逃逸
懒参数,而不在堆
中分配
局部变量,会导致泄漏
某个栈域指针
的内存错误
.
extern(C) int printf(const char*,...) @safe;
auto foo(lazy double i) @safe
{
return { return i; } ;
}
auto bar() @safe
{
double i = 4.0;
return foo(i);
}
void baz() @safe
{
double[2] i = 3.14;
// 此值覆盖了4.0
// 用char[16] val = 'f'; 替代
// 可打印确定性垃圾
}
void main() @safe
{
auto x = bar();
baz();
printf("%f\n", x());
}
这打印
了错误的3.14
.潜在
编译器可识别懒参数
逃逸,并在堆上分配i=4.0
,但因为是单独
编译模型,不能通用
解决,因此应该拒绝
代码.
这是已知引用-引用
错误的更复杂
变体,包括返回
出域的本地对象
的引用
:
ref int foo(ref int i) { return i; }
ref int bar() { int val; return foo(i); }
这是简化
版本,它更好地解释了懒
原理,并演示了类似
的问题(也打印垃圾):
import std.stdio;
alias long[10] T;
T delegate() dg;
void foo(ref T i) @safe
{
dg = { return i; } ;
}
void bar() @safe
{
T i = 1;
foo(i);
}
void rewrite_stack() @safe
{
T tmp = -1;
}
void main()
{
bar();
rewrite_stack();
writeln(dg());
}
另一个测试用例:
//test.d
@safe:
auto toDg(E)(lazy E value)
{
return { return value; };
}
C t;
class C
{
auto getDg()
{
// return () => prop;
return toDg(prop);
}
final @property string prop()
{
assert(this is t);
return null;
}
}
void smashStack() {
int[1024] dummy = 0xcafebabe;
}
void main()
{
t = new C();
auto result = t.getDg();
smashStack();
result();
}
编译器
要么拒绝
代码(接受无效
代码),要么生成闭包
(错误码).
升级严重级
,因为在@safe
代码中,(根据是否覆盖栈)表现为潜在
错误.
正是因为此
类问题,我有个dip
来弃用懒
参数,用闭包
代替它们,所以该特殊
问题可能不会
得到解决.
同时,我建议用闭包
替换lazy
参数.
降级懒
到闭包,所以降级
到正确的闭包类型
并得到正确
行为应该很容易,2022
年有一个dconf
在线讨论.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现