为了账号安全,请及时绑定邮箱和手机立即绑定

GCC的_属性_(包装)/#语用包不安全吗?

GCC的_属性_(包装)/#语用包不安全吗?

C++ C
温温酱 2019-06-25 13:50:42
GCC的_属性_(包装)/#语用包不安全吗?在C中,编译器将按照声明的顺序排列结构的成员,在成员之间插入可能的填充字节,或者在最后一个成员之后插入字节,以确保每个成员正确地对齐。GCC提供了语言扩展,__attribute__((packed)),它告诉编译器不要插入填充,从而允许结构成员对齐。例如,如果系统通常需要所有int对象具有4字节对齐,__attribute__((packed))能引起int将在奇数偏移量处分配的结构成员。引用GCC文献:“打包”属性指定变量或结构字段应该具有最小的对齐方式-变量为一个字节,字段为一个位,除非您用“对齐”属性指定更大的值。显然,使用这个扩展会导致较小的数据需求,但代码会更慢,因为编译器必须(在某些平台上)生成代码,以便一次访问错误对齐的成员。但有什么不安全的情况吗?编译器是否总是生成正确(尽管速度较慢)代码来访问打包结构的错误对齐成员?它在所有情况下都有可能这样做吗?
查看完整描述

3 回答

?
慕慕森

TA贡献1856条经验 获得超17个赞

正如上面所述,不要拿出一个指向一个结构的成员的指针。这只是玩火而已。当你说__attribute__((__packed__))#pragma pack(1)你真正说的是“GCC,我真的知道我在做什么。”当事实证明你没有,你不能责怪编译器。

也许我们可以因为编译器的自满而责怪它。而GCC确实有-Wcast-align选项时,默认情况下不启用该选项,也不使用-Wall-Wextra..这显然是因为GCC的开发人员认为这类代码是脑死亡的。“憎恶“不值得提及

考虑以下几点:

struct  __attribute__((__packed__)) my_struct {
    char c;
    int i;};struct my_struct a = {'a', 123};struct my_struct *b = &a;int c = a.i;int d = b->i;int *e __attribute__((aligned(1))) = 
    &a.i;int *f = &a.i;

在这里,类型a是一个打包的结构(如上面所定义的)。同样,b是指向打包结构的指针。表达式的类型a.i是(基本上)一个intL值1字节对齐。cd都是正常的int读书时a.i编译器生成未对齐访问的代码。当你读到b->ib他的类型仍然知道它很拥挤,所以他们也没问题。e是指向单字节对齐int的指针,因此编译器也知道如何正确地取消引用。但是当你做这个任务的时候f = &a.i,您正在将未对齐int指针的值存储在对齐int指针变量中-这就是您出错的地方。我同意,GCC应该让这个警告违约(甚至在-Wall-Wextra).


查看完整回答
反对 回复 2019-06-25
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

只要您始终通过结构通过.(点)或->符号。

什么Safe是将未对齐数据的指针取出来,然后访问它,而不考虑这一点。

此外,即使已知结构中的每一项都是对齐的,但已知它是对齐的。以一种特殊的方式因此,结构作为一个整体必须按照编译器的预期对齐,否则就会有麻烦(在某些平台上,或者在将来,如果发明了一种优化未对齐访问的新方法)。


查看完整回答
反对 回复 2019-06-25
  • 3 回答
  • 0 关注
  • 1670 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信