Tag: 字节顺序

为什么8位字段具有字节序?

请参阅/netinet/tcp.h中TCP头的定义: struct tcphdr { u_int16_t th_sport; /* source port */ u_int16_t th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ # if __BYTE_ORDER == __LITTLE_ENDIAN u_int8_t th_x2:4; /* (unused) */ u_int8_t th_off:4; /* data offset */ # endif # if __BYTE_ORDER == __BIG_ENDIAN u_int8_t th_off:4; /* data […]

是否需要转换字符串的字节顺序?

发送和接收字符串时是否需要转换为网络/主机字节顺序。 可用的函数(例如htons())仅适用于16位和32位整数。 我也知道一个事实,一个char不应该有所作为,因为通常,它是一个字节大。 然而呢?字符串呢? 以下是代码段 int len; recv(fd, &len, sizeof (int), 0); len = ntohl(len); char* string = malloc(sizeof (char) * (len + 1)); int received = recv(fd, string, sizeof (char) * len, 0); string[len] = ‘\0’;

在C ++程序中以编程方式检测字节顺序

是否有一种编程方式来检测您是否处于big-endian或little-endian架构? 我需要能够编写将在Intel或PPC系统上执行的代码并使用完全相同的代码(即没有条件编译)。

这段代码将如何在大端机器上运行?

如果我有代码: uint64_t a = 0x1111222233334444; uint32_t b = 0; b = a; printf(“a is %llx “,a); printf(“b is %x “,b); 输出是: a is 1111222233334444 b is 33334444 问题 : 大端机器上的行为是否相同? 如果我在b中指定一个值或者进行类型转换,那么大端的结果是否相同?

C中的endianess检测和性能

我有一个性能关键的C代码需要在各种平台上工作。 其中一些是小端,另一些是大端。 基于宏观检测,检测字节序目前是不完美的过程。 但很难确定宏检测是否适用于系统和编译器的所有组合。 欢迎来到便携式代码世界。 检测endianess的一种相对安全的方法是使用运行时测试,并希望它将被编译器优化。 这些方面的东西: static const int one = 1; #define IS_LITTLE_ENDIAN (*(char*)(&one)) 一般来说它有效。 编译器应正确检测到该宏的结果对于给定的体系结构总是相同的(1表示小端,0表示大端),只需完全删除内存访问和关联的分支。 我的问题是:总是如此吗? 我们是否可以期望编译器始终正确理解此测试,并始终正确地优化它? (假设-O2 / -O3或等效的优化级别,当然不适用于调试代码) 我特别担心双端CPU ,比如ARM。 由于这样的CPU可以是大端或小端,取决于OS参数,编译器可能难以“硬连线”这样的端序测试。 另一方面,我不希望应用程序以“任一端选择模式”工作:我想它应该编译为一个精确和明确的endianess。 因此,IS_LITTLE_ENDIAN应始终保持相同。 无论如何,我要求遇到遇到这种情况的人的经历。 由于我目前没有双端CPU和编译器,我无法测试并观察上述假设。 [ 编辑 ] @Brandin建议“保存宏的结果”,使其成为一个变量。 我猜他提出这样的事情: static const int one = 1; static const int isLittleEndian = *(char*)(&one); 由于在编译时会计算静态const int,因此确实可以保证编译器必须知道isLittleEndian的值,因此可以正确地优化使用此变量的分支。 不幸的是,它不起作用。 上述声明导致以下编译错误: error: initializer element is […]

通过并集和位移读取双平台字节序,是否安全?

我所看到的所有从缓冲区到平台字节序读取已知字节序的两倍的例子包括检测当前平台的字节顺序并在必要时执行字节交换。 另一方面,除了使用位移的整数( 一个这样的例子 )之外,我已经看到了另一种做同样事情的方法。 这让我觉得有可能使用union和bitshift技术从缓冲区中读取双精度(和浮点数),并且快速测试实现似乎有效(至少在x86_64上使用clang): #include #include #include double read_double(char * buffer, bool le) { union { double d; uint64_t i; } data; data.i = 0; int off = le ? 0 : 7; int add = le ? 1 : -1; for (int i = 0; i < 8; i++) { data.i |= ((uint64_t)(buffer[off] […]

为什么inet_ntoa和inet_ntop“反转”字节?

这是一个相当基本的问题,令我惊讶的是,我今天遇到了一个问题。 它看起来像inet_pton和inet_ntoa正在反转他们给出的IP地址的字节: DWORD IP; inet_pton(AF_INET, “192.168.0.1”, &IP); printf(“%08X\n”, IP); 这将打印0100A8C0 。 好吧,如果我们分解字节,它是01.00.A8.C0 = 1.0.168.192 。 同理: IP = 0x7F000001; struct in_addr ia; ia.S_un.S_addr = IP; printf(“%s\n”, inet_ntoa(ia)); 给了我1.0.0.127 。 首先想到的是endianness,但我已经阅读了MSDN文档( 1和2 )并且没有提到字节顺序; 这对我来说似乎很奇怪,这些函数会随意决定使用其中一种符号而没有明确说明。 到底是怎么回事?

关于小端和大端的按位非运算符(〜在C中)

这与家庭作业有关,但这不是家庭作业。 我很难理解,如果在大端机器和小端机器上编译时,按位不是( ~在C中)会如何影响signed int和unsigned int 。 字节是否真的 “向后”,如果是,那么按位(和其他运算符)是否会导致根据机器类型产生不同的结果? 虽然我们在这里,对于C中的每个按位运算符,答案是否相同,还是它依赖于它? 我所指的运营商是: ~ /* bitwise Not */ & /* bitwise And */ | /* bitwise Or */ ^ /* bitwise Exclusive-Or */ 先感谢您! 更新:到目前为止,在阅读我的回复时,我觉得有必要问一下bitwise not运算符是否会影响signed int上的符号位。 因为我忘了这一切,所以我担心这部分有点困惑。 亚当似乎在说所有的价值都被视为无符号。 是重新应用符号位还是一次签名的值变为无符号?

在C中交换endiannes

我有这个字符串 c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000 如何交换它以便它变成 000000000036cd35a97b0ff1974adde3ab5aff4dfc1379265b0108074f04ebc1 这两个基本上都是例子,但这就是我需要做的事情,但不知道我对C的了解很少。 上面两个字符串实际上是C程序中的unsigned char [] PS不要以为我没有通过谷歌。 我做了,但我发现我需要的东西很少,所以每次尝试都失败了。

如何BSWAP低32位的64位寄存器?

我一直在寻找如何将BSWAP用于64位寄存器的低32位子寄存器的答案。 例如, 0x0123456789abcdef在RAX寄存器中,我想用一条指令将其更改为0x01234567efcdab89 (因为性能)。 所以我尝试了以下内联函数: #define BSWAP(T) { \ __asm__ __volatile__ ( \ “bswap %k0” \ : “=q” (T) \ : “q” (T)); \ } 结果是0x00000000efcdab89 。 我不明白为什么编译器就像这样。 有人知道有效的解决方案吗?