【问题标题】:Why can't I return a reference to a packed field?为什么我不能返回对打包字段的引用?
【发布时间】:2014-12-16 03:47:06
【问题描述】:

我使用 g++ 编译带有压缩字段的代码。但是,我在尝试返回对打包字段的引用时收到错误消息。

例子:

struct __attribute__((packed)) Foo {
   int* ptr;
   uint16_t foo;
   int*& getPtr(){
      return ptr;
   }
};

产生错误:

test.cpp:22:14: error: cannot bind packed field ‘((Foo*)this)->Foo::ptr’ to ‘int*&’
   return ptr;

为什么我不能返回对打包字段的引用?

【问题讨论】:

  • 如果是打包的,字段可能没有正确对齐。
  • @T.C.:有没有办法告诉 gcc “螺丝对齐,我在 x86 上”?
  • @gexicide return (int*&)ptr;

标签: c++ c++11 gcc reference packed


【解决方案1】:

有一个 gcc 错误报告 Cannot bind packed field 涵盖了这一点,它说:

C++ 规范(C++03,第 3.9、3.9.1、3.9.2 节)非常清楚 T 和“指向 T 的指针”具有特定于实现的对齐要求。如果您有一个“指向 T 的指针”,那么您可以假设它满足对齐要求。我确信 C 规范有类似的语言。

在 OP 的情况下,以下代码可能违反对齐要求

他们建议使用alignment 属性定义您自己的对齐类型的解决方法,但它看起来不起作用。

【讨论】:

  • 不要相信,刚刚发现了同样的错误报告,并准备发布完全相同的报价......
  • 我尝试了使用 alginment 属性的解决方法。它被我的 gcc 忽略了。
  • 如果我可以有一个指向数据包字段的指针,为什么我不能有一个对打包字段的引用?在这两种情况下,成员的地址都是已知的。
  • 因为不是所有平台都支持字节可寻址内存,返回未对齐的结构会导致访问返回值时出现运行时段错误。
  • 在不可字节寻址的架构上,编译器仍然允许您通过在后台进行内存转换(例如屏蔽和移位)来访问非对齐字段以获得所需的值。它只知道这样做是因为结构是在编译时打包的。如果编译器丢失了打包信息,那么它可能会尝试直接访问不受支持的内存位置并且会出现硬故障。即使在 OPs 问题中它没有任何区别,GCC 也会谨慎行事并禁止该操作。
猜你喜欢
  • 2018-06-13
  • 1970-01-01
  • 2016-05-06
  • 2020-02-11
  • 2020-01-09
  • 1970-01-01
  • 2017-12-08
  • 1970-01-01
相关资源
最近更新 更多