d不变放进只读节,实现强制不变
原文
目前,D
编译器把串字面
放进只读节
中,但大多数其他类型静态不变
数据没有针对恶意写入
保护.
这里是不变崩溃的例子.
问题是,抛异常时,d运行时修改了静态不变
的异常
实例.问题也与它有关.
如果把不变
对象放进只读段
中,且运行时任意写,都触发段错误
,那么更易
解决此类问题.微控制器的裸代码
也可能从中受益,因为这样可把CTFE
生成的不变
数据放入NOR
闪存,而不浪费SRAM
空间.
怎么样,需要新的DIP
吗?
我试过使用DMD
代码,并把数组
字面放入只读节
.
要使其正确,还需要更多
工作.不变
标志还有问题.
如果类和构
实例有构造器
,还会删除不变
标志.但是这与CTFE
生成数据
真有关系吗?
检测数据是否由CTFE
生成,也不是很明显.用.ownedByCtfe
得到的结果很奇怪.有提示吗?
正确
实现它不是很困难吗?因为不能真正
把数据放入只读
内存,但必须保护整个页,如在窗口
上用VirtualProtect()
.特别是如何让GC
仍可分配
不变数据.或我不理解这方面的?
当然,字面
可且应设置为只读
,但对全部不变
数据,我不觉得对.
不变
好处是什么?
好处
一旦初化
不变数据,就永远不变
.有很多用法:
1,多线程
读取不变
数据时,不需要同步
的访问数据.
2,处理不变
数据时,没有数据竞争,撕裂,顺序一致性和缓存一致性
问题.
3,深度
复制数据结构时,不需要复制不变
部分.
4,即使通过引用
传递(串
最常见),也可按值类型
对待不变
的大块数据
.
5,不变
类型,提供了更多的自文档化
信息.
6,不变
数据可放在硬件保护
的只读
存储器中,甚至可放在ROM
中.
7,如果更改
了不变
数据,则肯定是内存
崩溃错误,并且可自动
检查此类数据完整性
.
8,不变
类型提供了许多优化
机会.
9,常
充当可变
和不变
世界间的桥梁
,因此单个函数可用常
来接受两种类型
参数.
我总按必须在编译时
构造,并可把不变
放进程序的RO
节,来理解不变
.
是的,但这不是现实.可在运行时
构造不变
数据,并且在共享静态构造器
等中经常这样.你的变化破坏性太大,突然不能这样了.
如,以下程序有效:
import std.stdio : writeln;
import std.datetime : Clock;
immutable int a;
shared static this()
{
a = Clock.currTime().year;
}
void main()
{
writeln(a);
}
上例中,"a"
不能放在只读
存储器中.
此时,可用'常'
关键字.
所以他特别指出静态不变
的而不仅是不变
.
我在早先消息中提到了静态不变
和CTFE
.一些不变
数据是在编译时
生成的,可安全地进入只读
节.现在只对改进
这一点感兴趣.
但是,既然你提到了抓GC
分配的不变
数据的写访问
,那么可借助额外的工具
来完成.可用valgrind
.
#include <stddef.h>
#include <valgrind/memcheck.h>
void vg_mark_block(void *p, size_t size)
{
int valgrind_handle = VALGRIND_CREATE_BLOCK(p, size, "MARKED BLOCK");
VALGRIND_MAKE_MEM_NOACCESS(p, size);
}
extern(C) void vg_mark_block(void *p, size_t size) @nogc;
void main() @nogc {
try {
static immutable e = new Exception("test");
vg_mark_block(cast(void*)e, __traits(classInstanceSize, typeof(e)));
throw e;
} catch (Exception e) {
assert(e.msg == "test");
}
}
插件未来可抓GC
分配支持的不变数据的写访问.已在ldc
中.然而,就像valgrind
一样,目前ASAN
不支持毒化内存
区域为只读
.
如果更改"immutable int a;"
为"immutable int a = 2030;"
,编译器会拒绝你的构造器
.
如果同时声明和初化
变量,那么把它放进只读
节可能是安全的.如果错了,请纠正.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现