2

Why is casting a string to an ubyte[] force to be unsafe in D?

And why is the same case using std.conv:to unsafe and nothrow?

I can very well understand that the opposite (casting ubyte[] to UTF-8) must be unsafe and throw but not this case?

Why can't I safely investigate these individual bytes?

4

3 回答 3

6

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

to!(ubyte[])(some_string)为我工作,即使在安全模式下,虽然它可以抛出。原因是 std.array 中的 appender 辅助函数没有正确标记为 nothrow;火卫一臭虫。如果将 nothrow 添加到 std/array.d 第 2662 行(在 dmd 2.064.2 中),它也会编译为 nothrow。

于 2013-11-10T23:43:44.590 回答
5

@safe与UTF -8 与 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")是一个实现问题。它绝对应该是可能的,我认为它可能是,因为它不需要解码字符,但底层实现不支持,可能是因为 Phobos 使用的许多低级东西不支持, , 或尚未支持,即使它应该支持。这种情况正在改善(例如 dmd 2.064,现在在某些情况下可能会改善),但还有很长的路要走。@systemnothrow@safenothrow@safepurenothrowformatpure

至于“调查单个字节”,我根本不明白为什么需要进行任何转换。只需遍历string's 元素。它们是char,其大小和符号与 完全相同ubyte。但是,如果您真的想在无需分配的情况下将其string作为数组进行操作,则只需将其转换为与- 例如ubytestring

auto arr = cast(immutable(ubyte)[])"hello world";

或者

auto arr = to!(immutable(ubyte)[])("hello world");
于 2013-11-10T23:51:16.240 回答
2

另请参见std.string.representation

于 2013-11-12T16:16:38.243 回答