我正在学习D编程语言,我试图将自己限制在尽可能的SafeD子集中.但是,我注意到像writeln这样的I/O函数都是@system.如何在SafeD中进行I/O操作?
我在Fedora 19 x86-64上使用LDC2(从Fedora包下载).
你没有,或者至少没有直接.I/O需要进行系统调用,这意味着C函数和C函数不会@safe
.而且由于writeln
目前printf
在引擎盖下调用,它肯定不会@safe
,因为用不安全的东西做printf
(例如给它%s
然后传递整数而不是字符串)是微不足道的.这或许有可能使writeln
@trusted
在某些情况下,但我不知道是什么都将与参与.这取决于它的实施方式.
完全可以预期,任何非平凡的D程序都将使用@system
代码.诀窍是隔离它.你的大部分程序都是有希望的@safe
,但它的部分内容必须如此@system
.但是,您只需要检查程序的一小部分内存安全性.一旦您手动验证调用@system
函数的函数实际上是内存安全的,您可以将其标记为@trusted
,然后您可以在@safe
代码中使用它.
不幸的是,druntime和Phobos中的某些核心内容也很可能@system
基于它在低级别内容中所做的事情,并且不一定所有内容都@trusted
应该被标记为(例如std.array.appender
可能@system
应该是它应该的时候)能够@trusted
- 我不确定它目前是什么;它可能取决于你的数组的元素类型).因此,为了更好地支持@safe
(这正在进行中,但我不知道现在所有这些都在哪里),可能需要对某些标准库的内容进行一些改进,并且您最终可能需要@trusted
现在在更多地方使用,而不是将来使用.writeln
可能是也可能不是@safe
或@trusted
在将来.但它绝对不会是如果你与它使用的类型不具备@safe
或@trusted
toString
功能,所以是否一部分writeln
是@safe
不管取决于它是如何实现在你使用它什么.然而,这不是当前@safe
或者@trusted
甚至内置类型,所以现在,你的运气了.
如果你真的想,你可以创建一个包装writeln
这是@trusted
的,但你必须要小心尤伯杯以确保代码实际上是内存的安全-而只需创建一个模板化的包装和标记它@trusted
是不会削减它,因为那时你会把它当作@safe
你传递给它的类型.因此,最好不要将其包装然后标记调用者,就@trusted
好像您确定该特定用途writeln
是内存安全一样.当然,这也突出了为什么函数writeln
目前@system
处于首位的部分原因:它通常很难编写@trusted
模板化代码,不信任不应信任的东西(因为它取决于模板参数).属性推断通常会解决问题,但如果模板化代码正在执行需要的操作@trusted
,则很难将代码的一部分标记为@trusted
并将其余部分留给推理,尤其是在模板参数与@system
内容混合的情况下.我希望我们最终会对所有标准库的东西进行排序.