c++ - 打包成员的引用地址不等于打包成员的地址?
问题描述
我用 g++ 编译了这个程序。它打印出“不平等”。
如果我不使用“packed”属性,它会打印“equal”。
我不知道“打包”属性如何导致差异。
顺便说一句,由 clang++ 构建的可执行文件打印“相等”。
#include <iostream>
struct __attribute__ ((packed)) Packed {
char a;
int b;
int c;
char d;
};
void test(const int &i, int *ptr) {
std::cout << ((&i == ptr) ? "equal" : "unequal") << std::endl;
}
int main () {
Packed p;
p.c = 1;
test(p.c, &p.c);
return 0;
}
解决方案
When compiling with GCC or CLANG, there is a warning saying that taking address of packed member of 'Packed' may result in an unaligned pointer value
which means that behavior of your code is unspecified. That's why you have different outputs when compiling with GCC and CLANG.
What does the __attribute__ ((packed))
mean?
The packed variable attribute specifies that a structure field has the smallest possible alignment. That is, one byte for a variable field, and one bit for a bitfield, unless you specify a larger value with the aligned attribute.
Why not to take the address of a packed member?
Taking the address of a packed member is dangerous since the reduced alignment of the pointee is lost. This can lead to memory alignment faults in some architectures if the pointer value is dereferenced.
References:
推荐阅读
- c# - 使用正则表达式 C# 从字符串中获取十进制值
- blockchain - 动态地将参与者添加到corda状态?
- javascript - Angular 2 在其他组件中显示具有相同数据的相同组件
- vim - Vim Formatprg 设置工作目录
- mysql - 如何在其他的基础上从表中选择数据
- sql-server - 具有高可用性组的多宿主 SQL Server
- php - Dompdf 样式不起作用
- oracle - 用于将 Ms Access 连接到 Oracle 数据库的 ODBC 连接
- content-management-system - Sitefinity 个性化 | 外部站点有限页面
- javascript - 在 Firebase 托管的 Angular 应用上托管 Unity WebGl