【发布时间】:2015-06-20 18:39:49
【问题描述】:
我正在尝试翻译这个 sn-p :
ntohs(*(UInt16*)VALUE) / 4.0
还有其他一些看起来相似的,从 C 到 Swift。 问题是,我对 Swift 知之甚少,我就是不明白这个 sn-p 是做什么的......这就是我所知道的:
-
ntohs将字节序交换为主机字节序 -
VALUE是char[32] - 我刚刚发现 Swift :
(UInt(data.0) << 6) + (UInt(data.1) >> 2)做同样的事情。能解释一下吗? - 我愿意返回 Swift
Uint(UInt64)
谢谢!
【问题讨论】:
-
将
char指针(或数组)转换为UInt16*是相当不安全的,并且可能导致未定义的行为。 -
这不是指针黑魔法。这只是重新诠释演员阵容。你应该看到一些真正的指针魔术......
-
@cmaster 这是未定义的行为,所以它不是好的魔法;-)
-
@zwol 我同意它没有以最好的方式编写。但是,如果您不能保证所使用的
char缓冲区的对齐,则它只是未定义的行为。如果该缓冲区是使用malloc()分配的,则它已充分对齐并且不会导致UB。但是,如果缓冲区在堆栈上,情况就不同了:编译器不需要以任何方式对齐char数组,这确实会导致理论上最糟糕的 UB。在实践中,UB 可能不会表现出来:缓冲区很有可能最终对齐,并且大多数 CPU 可以处理 16 位未对齐的读取。 -
@cmaster 根据基于类型的别名规则,这是未定义的行为,无论
VALUE分配在何处或如何对齐。它不会是 UB 的唯一方法是,如果VALUE本身已经从 转换为指向 (array-of-)UInt16的指针,并且指向的数据在两者之间没有被修改两个转换。但如果是这样的话,就没有必要打电话给ntohs了。
标签: c swift pointers endianness