You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自制Linux DNS服务器:不移动void指针访问数据的高效C实现?

DNS数据包偏移访问16位整数的优化实现

你当前的写法不仅冗长,还存在未对齐访问的风险(当pos为奇数时,强制转换为uint16_t*会指向未对齐地址,在ARM等架构上可能触发崩溃或性能损耗)。以下是几种更高效、简洁且安全的实现方式:

1. 手动字节组合(推荐基础写法)

先将void* data转换为字节指针,直接通过偏移读取单个字节并组合成16位整数——DNS协议使用大端字节序,这种写法等价于ntohs,且完全避免未对齐问题:

const uint8_t* buf = (const uint8_t*)data;
uint16_t val = ((uint16_t)buf[pos] << 8) | buf[pos + 1];

2. 封装为内联函数(兼顾简洁与安全)

把上述逻辑封装成内联函数,既简化调用,又避免宏可能带来的表达式重复计算副作用:

#include <stdint.h>
#include <stddef.h>

static inline uint16_t read_dns_u16(const void* data, size_t pos) {
    const uint8_t* buf = (const uint8_t*)data;
    return ((uint16_t)buf[pos] << 8) | buf[pos + 1];
}

// 调用示例
uint16_t val = read_dns_u16(data, pos);

3. 封装为宏(极致简洁)

如果追求代码最短,也可以用宏实现,但注意如果pos是复杂表达式(比如pos++),会重复计算:

#define READ_DNS_U16(data, pos) \
    (((uint16_t)*((const uint8_t*)data + pos) << 8) | \
     *((const uint8_t*)data + pos + 1))

// 调用示例
uint16_t val = READ_DNS_U16(data, pos);

这些实现都比你原来的写法更高效:一方面消除了未对齐访问的性能损耗或崩溃风险,另一方面避免了多层强制转换的冗余操作,编译器也能更轻松地优化代码。

内容的提问来源于stack exchange,提问作者Dimitris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 08:43:31