假设下面有非POD结构,对齐是否生效?如果没有,会有什么期待?
struct S1
{
string s;
int32_t i;
double d;
} __attribute__ ((aligned (64)));
编辑:下面的示例代码的输出是64甚至s被设置为长字符串。
int main(int argc,char *argv[])
{
S1 s1;
s1.s = "123451111111111111111111111111111111111111111111111111111111111111111111111111";
s1.i = 100;
s1.d = 20.123;
printf("%ld\n", sizeof(s1));
return 1;
}
答案 0 :(得分:1)
C ++中对象的大小永远不会改变。它是编译时间常量。它必须是,因为编译器需要知道为对象分配多少空间。事实上,sizeof(s1)
只是sizeof(S1)
的别名,后者不涉及任何实例。
std::string
是一个小对象,它将指针包装到字符数组并重新分配该数组以适应您设置的值。所以字符串本身存储在S1
对象之外。
__attribute__ ((aligned (64)))
不是标准C ++,而是GCC扩展。即使对于非POD对象,它也很荣幸。它只是告诉编译器将结构的大小四舍五入到下一个64字节的倍数。
虽然非POD对象很受尊重,但我无法想到将它用于一个POD对象的理由,并且只能想到将它用于POD对象的原因很少。默认对齐是合理的。你不需要调整它。
答案 1 :(得分:0)
是的,对齐在GCC中生效。
示例代码:
#include <string>
#include <iostream>
#include <cstddef>
using namespace std;
struct S1
{
string s;
int i;
double d;
} __attribute__ ((aligned (64)));
struct S2
{
string s;
int i;
double d;
} __attribute__ ((aligned)); // let the compiler decide
struct S3
{
string s;
int i;
double d;
};
int main() {
cout << "S1 " << sizeof(S1) << endl;
cout << "S2 " << sizeof(S2) << endl;
cout << "S3 " << sizeof(S3) << endl;
}
输出:
S1 64
S2 16
S3 16
另外:您发现S1
是非POD。请注意,std::string
允许在外部存储其数据(通常这样做是因为数据可以是任意长度,因此必须动态分配内存缓冲区。)
请记住,sizeof
仅在编译期间计算,不能依赖于运行时值。具体来说,您不能以这种方式查询动态分配的内存大小。
还要记住数组中的每个元素总是属于同一类型,因此大小也相同。