- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在开源中 program Iwrote ,我正在从文件中读取二进制数据(由另一个程序编写)并输出整数, double ,和其他各种数据类型。挑战之一是它需要在两种字节顺序的 32 位和 64 位机器上运行,这意味着我最终不得不做相当多的低级位操作。我知道一个(非常)关于类型双关语和严格别名的一些知识,想确保我以正确的方式做事。
基本上,很容易将 char* 转换为各种大小的 int:
int64_t snativeint64_t(const char *buf)
{
/* Interpret the first 8 bytes of buf as a 64-bit int */
return *(int64_t *) buf;
}
我有一系列支持函数可以根据需要交换字节顺序,例如作为:
int64_t swappedint64_t(const int64_t wrongend)
{
/* Change the endianness of a 64-bit integer */
return (((wrongend & 0xff00000000000000LL) >> 56) |
((wrongend & 0x00ff000000000000LL) >> 40) |
((wrongend & 0x0000ff0000000000LL) >> 24) |
((wrongend & 0x000000ff00000000LL) >> 8) |
((wrongend & 0x00000000ff000000LL) << 8) |
((wrongend & 0x0000000000ff0000LL) << 24) |
((wrongend & 0x000000000000ff00LL) << 40) |
((wrongend & 0x00000000000000ffLL) << 56));
}
在运行时,程序会检测机器的字节顺序并分配以上之一指向函数指针:
int64_t (*slittleint64_t)(const char *);
if(littleendian) {
slittleint64_t = snativeint64_t;
} else {
slittleint64_t = sswappedint64_t;
}
现在,当我尝试将 char* 转换为 double 时,棘手的部分就来了。 ID喜欢像这样重用字节序交换代码:
union
{
double d;
int64_t i;
} int64todouble;
int64todouble.i = slittleint64_t(bufoffset);
printf("%lf", int64todouble.d);
但是,一些编译器可以优化掉“int64todouble.i”赋值并中断程序。有没有更安全的方法来做到这一点,同时考虑这个程序必须保持性能优化,而且我会不想编写一组并行的转换来将 char* 转换为直接加倍?如果双关的 union 方法是安全的,我应该是重写我的函数,如 snativeint64_t 以使用它?
我最终使用了 Steve Jessop's回答是因为重写了转换函数以使用 memcpy,如下所示:
int64_t snativeint64_t(const char *buf)
{
/* Interpret the first 8 bytes of buf as a 64-bit int */
int64_t output;
memcpy(&output, buf, 8);
return output;
}
编译成与我的原始代码完全相同的汇编程序:
snativeint64_t:
movq (%rdi), %rax
ret
在这两个版本中,memcpy 版本更明确地表达了我正在尝试做的事情,即使是最天真的编译器也应该可以工作。
Adam,你的回答也很精彩,我从中学到了很多东西。感谢发帖!
最佳答案
我强烈建议您阅读 Understanding Strict Aliasing .具体来说,请参阅标有“通过 union 类型转换”的部分。它有很多很好的例子。虽然这篇文章是在一个关于 Cell 处理器的网站上并使用 PPC 汇编示例,但几乎所有内容都同样适用于其他架构,包括 x86。
关于c - 在 C 中安全地将 char* 双关语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/222266/
我想我已经找到了一种在 C# 中复制位图的更快的方法。 (如果它是有效的,我确定我不是第一个,但我还没有在任何地方看到它。) 我能想到的最简单的提问方式是断言我的想法是基于什么,如果没有人指出其中的漏
我正在为 PIC32MX 编写 C,使用 Microchip 的 PIC32 C 编译器(基于 GCC 3.4)编译。 已添加 我遵循的标准是 GNU99(C99 带有 GNU 扩展,编译器标志 -s
在开源中 program Iwrote ,我正在从文件中读取二进制数据(由另一个程序编写)并输出整数, double ,和其他各种数据类型。挑战之一是它需要在两种字节顺序的 32 位和 64 位机器上
这是我为学习 js 而编写的图片库中的一些清理代码。我将画廊创建为一个对象,但在某些时候我忘记了“this”指向的内容。底部发生的事情对我来说没有意义(看看评论)。有人可以解释一下吗? functio
我是一名优秀的程序员,十分优秀!