-1

下に非 POD 構造体があるとします。アライメントは有効ですか? そうでない場合、何が予想されますか?

struct S1
{
    string s;
    int32_t i;
    double d;
} __attribute__ ((aligned (64)));

編集: 以下のサンプル コードの出力は、s が長い文字列に設定されていても 64 です。

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オブジェクトに使用する理由はほとんどなく、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 に答える