pack
pragma
Menentukan perataan pengemasan untuk struktur, union, dan anggota kelas.
Sintaks
#pragma pack( show )
#pragma pack( push
[,
] [ ] [,
n
]identifier
)
#pragma pack( pop
[,
{identifier
|n
} ])
#pragma pack(
Aku akan menemuinya.n
)
Parameter
show
(Opsional) Menampilkan nilai byte saat ini untuk perataan pengemasan. Nilai ditampilkan oleh pesan peringatan.
push
(Opsional) Mendorong nilai perataan pengemasan saat ini pada tumpukan kompilator internal, dan mengatur nilai perataan kemasan saat ini ke n. Jika n tidak ditentukan, nilai perataan kemasan saat ini akan didorong.
pop
(Opsional) Menghapus rekaman dari bagian atas tumpukan kompilator internal. Jika n tidak ditentukan dengan pop
, maka nilai pengemasan yang terkait dengan rekaman yang dihasilkan di bagian atas tumpukan adalah nilai perataan kemasan baru. Jika n ditentukan, misalnya, #pragma pack(pop, 16)
, n menjadi nilai perataan kemasan baru. Jika Anda muncul menggunakan identifier
, misalnya, #pragma pack(pop, r1)
, maka semua rekaman pada tumpukan akan muncul hingga rekaman yang ditemukan identifier
. Rekaman itu akan muncul, dan nilai pengemasan yang terkait dengan rekaman yang ditemukan di bagian atas tumpukan menjadi nilai perataan kemasan baru. Jika Anda muncul menggunakan identifier
yang tidak ditemukan dalam rekaman apa pun di tumpukan, maka pop
diabaikan.
Pernyataan #pragma pack (pop, r1, 2)
ini setara dengan #pragma pack (pop, r1)
diikuti oleh #pragma pack(2)
.
identifier
(Opsional) Saat digunakan dengan push
, menetapkan nama ke rekaman pada tumpukan kompilator internal. Saat digunakan dengan pop
, memunculkan rekaman dari tumpukan internal hingga identifier
dihapus. Jika identifier
tidak ditemukan di tumpukan internal, tidak ada yang muncul.
n
(Opsional) Menentukan nilai, dalam byte, yang akan digunakan untuk pengemasan. Jika opsi /Zp
pengkompilasi tidak diatur untuk modul, nilai default untuk n
adalah 8. Nilai yang valid adalah 1, 2, 4, 8, dan 16. Perataan anggota berada di batas yang merupakan kelipatan dari n
, atau kelipatan ukuran anggota, mana pun yang lebih kecil.
Keterangan
Untuk mengemas kelas adalah menempatkan anggotanya langsung setelah satu sama lain dalam memori. Ini dapat berarti bahwa beberapa atau semua anggota dapat diselaraskan pada batas yang lebih kecil dari perataan default arsitektur target. pack
memberikan kontrol pada tingkat deklarasi data. Ini berbeda dari opsi /Zp
pengkompilasi , yang hanya menyediakan kontrol tingkat modul. pack berlaku pada deklarasi pertama struct
, , union
atau class
setelah pragma terlihat. pack
tidak berpengaruh pada definisi. Memanggil pack
tanpa argumen yang diatur n
ke nilai yang ditetapkan dalam opsi /Zp
pengkompilasi . Jika opsi pengkompilasi tidak diatur, nilai defaultnya adalah 8 untuk x86, ARM, dan ARM64. Defaultnya adalah 16 untuk x64 asli dan ARM64EC.
Jika Anda mengubah perataan struktur, itu mungkin tidak menggunakan ruang sebanyak dalam memori. Namun, Anda mungkin melihat hilangnya performa atau bahkan mendapatkan pengecualian yang dihasilkan perangkat keras untuk akses yang tidak ditandatangani. Anda dapat mengubah perilaku pengecualian ini dengan menggunakan SetErrorMode
.
Untuk informasi selengkapnya tentang cara mengubah perataan, lihat artikel berikut ini:
-
Peringatan
Di Visual Studio 2015 dan yang lebih baru, Anda dapat menggunakan standar
alignas
danalignof
operator, yang tidak seperti__alignof
dan__declspec( align )
portabel di seluruh pengkompilasi. Standar C++ tidak mengatasi pengemasan, jadi Anda masih harus menggunakanpack
(atau ekstensi yang sesuai pada kompilator lain) untuk menentukan perataan yang lebih kecil dari ukuran kata arsitektur target.
Contoh
Sampel berikut menunjukkan cara menggunakan pack
pragma untuk mengubah perataan struktur.
// pragma_directives_pack.cpp
#include <stddef.h>
#include <stdio.h>
struct S {
int i; // size 4
short j; // size 2
double k; // size 8
};
#pragma pack(2)
struct T {
int i;
short j;
double k;
};
int main() {
printf("%zu ", offsetof(S, i));
printf("%zu ", offsetof(S, j));
printf("%zu\n", offsetof(S, k));
printf("%zu ", offsetof(T, i));
printf("%zu ", offsetof(T, j));
printf("%zu\n", offsetof(T, k));
}
0 4 8
0 4 6
Contoh berikut menunjukkan cara menggunakan sintaks push, pop, dan show .
// pragma_directives_pack_2.cpp
// compile with: /W1 /c
#pragma pack() // n defaults to 8; equivalent to /Zp8
#pragma pack(show) // C4810
#pragma pack(4) // n = 4
#pragma pack(show) // C4810
#pragma pack(push, r1, 16) // n = 16, pushed to stack
#pragma pack(show) // C4810
// pop to the identifier and then set
// the value of the current packing alignment:
#pragma pack(pop, r1, 2) // n = 2 , stack popped
#pragma pack(show) // C4810