d取非静态方法地址
struct S {
int m(int x) {return x;}
}
void main() {
int function(int) func = &S.m;
writeln(func(5));// 不打印5!
}
不应编译
.
我一直在研究
该问题,似乎,令人惊讶
的是,这是期望
行为.我先修复它,但后来
发现,这是正确
代码.
现在,当谈论函数
时,有两类:函数或闭包
.函数由函数指针
表示,而闭包
由函数和环境指针
表示.
当取成员函数
地址时,编译器
只是简单地设置函数指针
为函数代码地址
.然而,(静态除外的)成员函数
也有在后台按第一个
参数传递的环境
指针.所以在报告代码
中,最终得到如下代码
:
int m(void* ctx, int x)
{
return x;// mov rax, rsi
//返回第2个参数
}
void main()
{
int function(int) func = &S.m;
// mov rax, m
func(5);
//mov rdi,5;
//jmp rax
}
因此得到了垃圾
.你得到了函数
地址,然后就像它只有一个参数
一样欺骗
编译器,调用m
.注意,如果函数的类型是闭包
,那么你正确得到了5
,因为现在编译器知道把ctx
(本例中是null)
传递给m
了.
不带环境取成员函数
实际地址是很有用
的.测试包中很多,如果禁止它,就别无选择.另一方面,如果用@safe
标记main
,就不能编译代码:
在安全代码中,要取`myFunc`成员地址,必须要加`this`.
因此,在安全
代码中这是禁止
的,但了解它的高级
用户可用此功能
.
所以这是无效错误报告
.
没有环境
指针,不应调用闭包
的函数指针
.
但可手动,设置环境和函数
指针:
struct S {
int m(int x) {return x;}
}
void main() {
import std.stdio;
int function(int) func = &S.m;
int delegate(int) func2;
S s;
func2.funcptr = func;
func2.ptr = &s;
writeln(func2(5));
}
&S.m
返回函数指针
,所以,函数
是可调用的.用户确保正确
使用它们.现在不能禁止取S.m
的地址.而改&S.m
类型,会产生更多问题.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现