-1

假设下面有非POD struct,对齐是否生效?如果没有,会发生什么?

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;
}
4

2 回答 2

1

C++ 中对象的大小永远不会改变。它是编译时间常数。必须如此,因为编译器需要知道为对象分配多少空间。实际上,sizeof(s1)只是别名,sizeof(S1)后面没有涉及任何实例。

std::string是一个小型对象,它包装指向字符数组的指针并重新分配该数组以容纳您设置的值。所以字符串本身存储在S1对象之外。

__attribute__ ((aligned (64)))不是标准的C++,它是 GCC 扩展。即使对于非 POD 对象,它也会受到尊重。它只是告诉编译器将结构的大小四舍五入到下一个 64 字节的倍数。

虽然它在非 POD 对象上很受欢迎,但我想不出将它用于一个对象的理由,只能想到很少的理由将它用于 POD 对象。默认对齐是合理的。你不需要调整它。

于 2012-11-27T10:13:02.507 回答
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它仅在编译期间计算,它不能依赖于运行时值。具体来说,您永远无法以这种方式查询动态分配的内存大小。

还要记住,数组中的每个元素总是具有相同的类型,因此也具有相同的大小。

于 2012-11-27T10:20:11.037 回答