(uint16_t*) 和 (uint32_t*) 有什么区别?
What is the difference between (uint16_t*) and (uint32_t*)?
如下代码所示,(uint16_t*)
用于s
,而(uint32_t*)
用于w
。为什么?此函数是否用于交换数据包中的目标 MAC 地址和源 MAC 地址?
static inline void
swap_mac_addr(uint64_t pkt_ptr)
{
uint16_t s;
uint32_t w;
/* assuming an IP/IPV6 pkt i.e. L2 header is 2 byte aligned, 4 byte non-aligned */
s = *(uint16_t*)pkt_ptr;
w = *(uint32_t*)(pkt_ptr+2);
*(uint16_t*)pkt_ptr = *(uint16_t*)(pkt_ptr+6);
*(uint32_t*)(pkt_ptr+2) = *(uint32_t*)(pkt_ptr+8);
*(uint16_t*)(pkt_ptr+6) = s;
*(uint32_t*)(pkt_ptr+8) = w;
}
该代码看起来好像在准备对以太网数据包的应答并交换数据包中的目标地址和源地址 header。
一个MAC地址有48位。即16+32,开发者决定使用16bit的数据类型加32bit的数据类型。正如已经指出的那样,这可能会也可能不会在现代的、积极优化的编译器上正常工作。即便如此,它可能无法在希望看到 32 位值与内存中的 32 位对齐的架构(例如 ARM)上运行。
代码最好将 MAC 地址视为一个字节数组,并使用 memcpy 移动字节。
从性能的角度来看,该构造 可能 在使用无法识别它可以使用大型寄存器传输的非常愚蠢的编译器(考虑到今天的标准)时很有帮助移动数据。在现代编译器上,即使它工作正常,这些东西甚至可能会对性能产生负面影响。
如下代码所示,(uint16_t*)
用于s
,而(uint32_t*)
用于w
。为什么?此函数是否用于交换数据包中的目标 MAC 地址和源 MAC 地址?
static inline void
swap_mac_addr(uint64_t pkt_ptr)
{
uint16_t s;
uint32_t w;
/* assuming an IP/IPV6 pkt i.e. L2 header is 2 byte aligned, 4 byte non-aligned */
s = *(uint16_t*)pkt_ptr;
w = *(uint32_t*)(pkt_ptr+2);
*(uint16_t*)pkt_ptr = *(uint16_t*)(pkt_ptr+6);
*(uint32_t*)(pkt_ptr+2) = *(uint32_t*)(pkt_ptr+8);
*(uint16_t*)(pkt_ptr+6) = s;
*(uint32_t*)(pkt_ptr+8) = w;
}
该代码看起来好像在准备对以太网数据包的应答并交换数据包中的目标地址和源地址 header。
一个MAC地址有48位。即16+32,开发者决定使用16bit的数据类型加32bit的数据类型。正如已经指出的那样,这可能会也可能不会在现代的、积极优化的编译器上正常工作。即便如此,它可能无法在希望看到 32 位值与内存中的 32 位对齐的架构(例如 ARM)上运行。
代码最好将 MAC 地址视为一个字节数组,并使用 memcpy 移动字节。
从性能的角度来看,该构造 可能 在使用无法识别它可以使用大型寄存器传输的非常愚蠢的编译器(考虑到今天的标准)时很有帮助移动数据。在现代编译器上,即使它工作正常,这些东西甚至可能会对性能产生负面影响。