liuxu

liuxu

没有最强的法术,只有最强的法师。
V2EX 第 62234 号会员,加入于 2014-05-09 03:02:29 +08:00
今日活跃度排名 5018
根据 liuxu 的设置,主题列表被隐藏
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
liuxu 最近回复了
10 小时 16 分钟前
回复了 slidoooor 创建的主题 程序员 整理了一波计算机书籍的综合评分列表
其实这个书籍排行榜没意义,应该和 jd 一样弄成同类书籍排行榜,我要看 linux 内核解析只能选那几本,虽然排名很低
10 小时 18 分钟前
回复了 LxnChan 创建的主题 Linux VNC 反代出去总是被爆破,又不想把黑名单设置为 0
fail2ban 解君愁
@liuxu 不过有的 vps 没有用 NetworkManager.service
$ journalctl -u NetworkManager --no-tail |grep dhclient
1 天前
回复了 mingl0280 创建的主题 C++ 问个关于内存对齐的问题
还有一种情况,系统和编译器都是 64 位,编译目标编译出了 32 位和 64 位程序,debug 分析的时候选择了 32 位程序。
1 天前
回复了 mingl0280 创建的主题 C++ 问个关于内存对齐的问题
@liuxu #17 修正一下,我之前是 32 位系统 debug 的,现在都是 64 位系统,情况有变化。

首先说结论:
1. 和编译的目标程序的位数有关,32 位程序最高是 4 字节(32 位)对齐,64 位程序最高是(8 字节)64 位对齐。
2. 在 1 的要求下,struct 中按最宽位数的变量对齐。结合 1 中的“最高”的意思是:
64 位程序:uint32_t + uint64_t + uint64_t 分配 24 字节(8+8+8)。
32 位程序:uint32_t + uint64_t + uint64_t 分配 20 字节(4+(4+4)+(4+4))。
32/64 位程序:uint8_t +uint16_t +uint8_t 分配 8 字节(2+2+2)。
3. 添加#pragma pack(4)后,32 位和 64 位程序都按 4 字节(32 位)对齐,也就是 uint32_t + uint64_t + uint64_t 都是 20 字节(4+(4+4)+(4+4))。但是如果 struct 最大为 uint16_t ,则依然按 2 字节对齐。(也就是说 pack 无法影响 struct 最大位宽限制)
4. 添加了#pragma pack(16)后,64 位依然按 8 字节(64 位)对齐。也就是说 pack 中的数字只能是不大于(系统位数 /8)的 2 的次方的数字。


所以楼主的情况, 如果代码中真的没有#pragma pack(),但是出现了帖子中的现象,只有可能是以下 3 中情况:
1. 楼主的系统是 32 位的。( 32 位系统只会运行 32 位编译器编译出 32 位程序)
2. 楼主的编译器是 32 位的。( 32 位编译器只会编译出 32 位程序)
3. 楼主 64 位 msvc 编译目标选择的是 32 位程序。(据我所知 vs 默认的 debuging 版本编译的是 32 位程序,至少我几年前 debug 的时候是的,也有可能是我创建项目的时候设置成了 32 位)。

即楼主 2 次编译的字节对齐方式为:
struct FixedLengthHeader {
uint32_t HeaderSize = 0;
uint64_t CryptogramSize = 0;
uint64_t ReservedField = 0;
}FixedPackageHeaders;
20 字节(4+(4+4)+(4+4))。

struct FixedLengthHeader {
uint32_t HeaderSize = 0;
uint64_t CryptogramSize = 0;
uint8_t DevFlag = 0;
uint8_t HeaderVer = 0;
uint32_t PackagerVer = 0;
uint16_t Reserved = 0
}FixedPackageHeaders;
24 字节(4+(4+4)+4+4+4)。

以上是 64 位 linux gcc 下的结果推测的 msvc 的结果,windows 下的实际结果还是得大佬们自己调试。



以下是我 GDB 打印情况:
系统:Ubuntu 20.04.3 LTS x86_64
gcc: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0


没有添加#progma pack(4),编译指令:gcc -g test.c

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* XXX 4-byte hole */
/* 8 | 8 */ uint64_t CryptogramSize;
/* 16 | 8 */ uint64_t ReservedField;

/* total size (bytes): 24 */
}
(8+8+8)

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* XXX 4-byte hole */
/* 8 | 8 */ uint64_t CryptogramSize;
/* 16 | 1 */ uint8_t DevFlag;
/* 17 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 20 | 4 */ uint32_t PackagerVer;
/* 24 | 2 */ uint16_t Reserved;
/* XXX 6-byte padding */

/* total size (bytes): 32 */
}
(8+8+8)

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 1 */ uint8_t DevFlag;
/* 5 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 8 | 4 */ uint32_t PackagerVer;
/* 12 | 2 */ uint16_t Reserved;
/* XXX 2-byte padding */

/* total size (bytes): 16 */
}
(4+4+4+4)


没有添加#progma pack(4),编译指令:gcc -m32 -g test.c

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 8 */ uint64_t CryptogramSize;
/* 12 | 8 */ uint64_t ReservedField;

/* total size (bytes): 20 */
}
(4+(4+4)+(4+4))

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 8 */ uint64_t CryptogramSize;
/* 12 | 1 */ uint8_t DevFlag;
/* 13 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 16 | 4 */ uint32_t PackagerVer;
/* 20 | 2 */ uint16_t Reserved;
/* XXX 2-byte padding */

/* total size (bytes): 24 */
}
(4+(4+4)+4+4+4)


添加#progma pack(4),编译指令:gcc -g test.c

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 8 */ uint64_t CryptogramSize;
/* 12 | 8 */ uint64_t ReservedField;

/* total size (bytes): 20 */
}
(4+(4+4)+(4+4))

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 8 */ uint64_t CryptogramSize;
/* 12 | 1 */ uint8_t DevFlag;
/* 13 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 16 | 4 */ uint32_t PackagerVer;
/* 20 | 2 */ uint16_t Reserved;
/* XXX 2-byte padding */

/* total size (bytes): 24 */
}
(4+(4+4)+4+4+4)


添加#progma pack(16),编译指令:gcc -g test.c

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* XXX 4-byte hole */
/* 8 | 8 */ uint64_t CryptogramSize;
/* 16 | 1 */ uint8_t DevFlag;
/* 17 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 20 | 4 */ uint32_t PackagerVer;
/* 24 | 2 */ uint16_t Reserved;
/* XXX 6-byte padding */

/* total size (bytes): 32 */
}
(8+8+8+8)
2 天前
回复了 mingl0280 创建的主题 C++ 问个关于内存对齐的问题
你下面的不是
24 字节(4+8+2+2+4+4 )
而是
24 字节(4+8+4+4+4 )

你试试
struct FixedLengthHeader {
uint32_t HeaderSize = 0;
uint64_t CryptogramSize = 0;
uint8_t DevFlag = 0;
uint8_t HeaderVer = 0;
uint16_t Reserved = 0;
uint32_t PackagerVer = 0;
}FixedPackageHeaders;

应该会变成 4+8+4+4=20

应该是编译器优化结果

8|8|32 的位地址占用情况应该是
1111 1111 1111 1111 xxxx xxxx xxxx xxxx
1111 1111 1111 1111 1111 1111 1111 1111
也就是 2 个 8 后面空着不要了

但是如果 8|8|8/16|32,不会再多分配内存,继续复用没有用的 16 位空间
@jdz rust 强力支撑不是我说的,是作者说的,原因是用了 rust 正则引擎
但是不应该对用了几十年的老工具抱有轻蔑的态度,毕竟互联网能发展起来它们是基石
那是自然,rust 强力支撑
关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1357 人在线   最高记录 5497   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 9ms · UTC 23:32 · PVG 07:32 · LAX 16:32 · JFK 19:32
♥ Do have faith in what you're doing.