如何在D中的@safe函数中进行I/O?

如何在D中的@safe函数中进行I/O?,d,D,我正在学习D编程语言,我试图尽可能地将自己局限于它的安全子集。然而,我注意到像writeln这样的I/O函数都是@system。如何在SafeD中进行I/O 我正在Fedora19 x86-64上使用LDC2(从Fedora软件包下载)。您没有,或者至少没有直接使用。I/O需要进行系统调用,这意味着C函数,而C函数不会是安全的。而且由于writeln目前在引擎盖下调用printf,它肯定不会是@safe,因为使用printf做不安全的事情是微不足道的(比如给它%s,然后传递一个整数而不是字符串)

我正在学习D编程语言,我试图尽可能地将自己局限于它的安全子集。然而,我注意到像writeln这样的I/O函数都是@system。如何在SafeD中进行I/O


我正在Fedora19 x86-64上使用LDC2(从Fedora软件包下载)。

您没有,或者至少没有直接使用。I/O需要进行系统调用,这意味着C函数,而C函数不会是安全的。而且由于
writeln
目前在引擎盖下调用
printf
,它肯定不会是
@safe
,因为使用
printf
做不安全的事情是微不足道的(比如给它
%s
,然后传递一个整数而不是字符串)。在某些情况下,可能会使
writeln
@可信
,但我不知道这会涉及到什么。这将取决于它是如何实现的

完全可以预料,任何非平凡的D程序都将使用
@system
代码。诀窍是将其隔离。您的程序的大部分希望是
@safe
,但它的部分必须是
@system
。但是,您只需检查程序的一小部分以确保内存安全。一旦手动验证调用
@system
函数的函数实际上是内存安全的,您可以将其标记为
@trusted
,然后可以在
@safe
代码中使用它

不幸的是,druntime和Phobos中的某些核心内容也很可能是基于它对低级内容的处理,而不一定所有内容都被标记为应该的
@trusted
(例如,
std.array.appender
可能是
@system
,但它可能是
@trusted
-我不确定它当前是什么;它可能取决于数组的元素类型).因此,为了更好地支持
@safe
(这项工作正在进行中,但我现在不知道这些都在哪里),可能需要对一些标准库的内容进行一些改进,您现在可能不得不在比将来更多的地方使用
@trusted
writeln
将来可能会或可能不会
@safe
@trusted
。但如果您使用的类型没有
@safe
@trusted
,则肯定不会字符串
起作用,因此
writeln
是否安全部分取决于您使用它的方式,而不管它是如何实现的。但是,即使使用内置类型,它当前也不是
@safe
@trusted
,所以现在,您运气不佳


如果你真的想,你可以为
@writeln
创建一个受信任的
包装器,但是你必须非常小心,确保代码实际上是内存安全的——并且简单地创建一个模板包装器并将其标记为
@trusted
不会剪切它,因为这样你就可以将其视为
@safe。因此,如果您确信
writeln
的特定使用是内存安全的,那么最好不要包装它,然后将调用方标记为
@trusted
。当然,这也突出了为什么像
writeln
这样的函数当前在第一个系统中是
@system
t place:如果不信任不应该信任的东西,编写
@trusted
模板化代码通常很困难(因为它取决于模板参数).属性推断通常会解决这个问题,但是如果模板化代码正在做一些需要信任的事情,则很难将代码的一部分标记为受信任的,而将其余部分留给推断,特别是当模板参数与
@system
内容混合在一起时。我希望我们不过,我最终会对所有标准库的内容进行分类。

我认为我们应该让writeln和friends
@受信任
——尽管他们使用低级原语,但他们会进行足够的检查,以确保例如printf不会收到混乱的参数。

这很有意义,尤其是作为最坏的罪犯不管怎样,大多数代码都可以避免内存中的安全IMO(指针)(实际的低级函数除外).@Demetri完全正确。你的程序中有
@system
代码,但它是孤立的,而且它通常是一个足够小的部分,你可以自己验证它的内存安全性,而如果你根本没有
@safe
,你就必须自己验证整个程序,这显然要困难得多。writefln surey可以被设置为@safe,除了自动打印char*之外,因为可能没有零终止符(这是否真的使它进入?或者它只是将指针显示为十六进制?)它根本不需要使用printf——我们已经有了std.format.formattedWrite来完成大部分工作,那么对C的最后调用也可以进行验证,或者类似于fwrite()的东西这是非常明智的。至少@trusted@AdamD.Ruppe我希望
writeln
可能是安全的,只要参数具有适当的
@safe
功能(例如
@safe
),但不能简单地将其标记为
@trusted
@safe
,我不知道标记适当的
@trusted
而不标记不应
@trusted
@trusted
部分会有多容易。因此,根据实现情况,这可能会有点麻烦。我希望我们能够获得您不能对自定义类的to!字符串调用可能不是@safe,这不一定是dealbreaker