安全地调查D中字符串的单个字节

Nor*_*löw 2 arrays string byte casting d

为什么是cast荷兰国际集团一stringubyte[]部队是在d不安全?

为什么同样的情况使用std.conv:to不安全和不安全?

我可以很好地理解相反的(转换ubyte[]为UTF-8)必须是不安全的并抛出但不是这种情况?

为什么我不能安全地调查这些单独的字节?

Ada*_*ppe 6

字符串 - > ubyte在安全模式下是不允许的,因为这会丢弃字符串的不变性.cast(immutable(ubyte)[]) some_string是允许的.您还可以通过执行查看字符串的字节foreach(char c; some_string) { /* look at c */ }.

to!(ubyte[])(some_string)虽然它可以投掷,但即使在安全模式下也能为我工作.原因是因为std.array中的appender helper函数没有正确标记为nothrow; 一个phobos bug.如果你将nothrow添加到std/array.d第2662行(在dmd 2.064.2中),它将编译为nothrow.


Jon*_*vis 5

@safe没有做UTF-8 VS ASCII.@safe与记忆安全有关.这样可以保证您不会在已发布或损坏的内存上运行.许多类型的强制转换被认为是@system不安全的,因为它们冒着做违反内存安全的事情的风险,并且它要求程序员验证强制转换实际上没有违反内存安全性并将函数标记@trusted为告诉编译器它实际上是安全,使其在@safe代码中可用.

至于铸造stringubyte[],虚掷immutable喜欢就是规避类型系统.它使得必须保证你的代码不会改变数据,如果你不这样做,你就违反了编译器的保证,你就会遇到错误.我建议看看

D中const和immutable有什么区别?

D中的逻辑常量

长话短说,不要丢弃constimmutable除非你真的需要,你知道你在做什么.

std.conv.todup是否具有为了做一个转换,使一个阵列to!(ubyte[])("hello world")将要产生新的ubyte[]具有作为相同的值"hello world",但它不会在相同的阵列,因此不会违反的类型系统.如果它已经to!(immutable(ubyte)[])("hello world"),那么它可以转换数组,但只要你转换为可变数组就不能.

至于to!(ubyte[])("hello world")@systemnothrow,这是一个实现问题.它应该是可能的@safe,并且我认为它可以nothrow,因为它不需要解码字符,但底层实现不支持它,可能是因为Phobos使用的大部分低级别的东西不支持@safe,pure或者nothrow甚至不支持.这种情况正在改善(例如,使用dmd 2.064,format现在可以pure在某些情况下使用),但仍有很多方法可以实现.

至于"调查单个字节",我不明白为什么你需要进行任何转换.只是迭代string的元素.它们char的大小和签名完全相同ubyte.但是如果你真的想在不必分配stringubyte情况下对数组进行操作,那么只需转换为相同的常量string- 例如

auto arr = cast(immutable(ubyte)[])"hello world";
Run Code Online (Sandbox Code Playgroud)

要么

auto arr = to!(immutable(ubyte)[])("hello world");
Run Code Online (Sandbox Code Playgroud)