Bagikan melalui


init_seg pragma

C++ Spesifik

Menentukan kata kunci atau bagian kode yang memengaruhi urutan di mana kode pengaktifan dijalankan.

Sintaks

#pragma init_seg( { compiler | lib | user | "section-name" [ ,func-name ] } )

Keterangan

Segmen dan bagian istilahmemiliki arti yang sama dalam artikel ini.

Karena kode terkadang diperlukan untuk menginisialisasi objek statis global, Anda harus menentukan kapan harus membuat objek. Secara khusus, penting untuk menggunakan init_segpragma pustaka tautan dinamis (DLL), atau di pustaka yang memerlukan inisialisasi.

Opsi untuk init_segpragma adalah:

compiler
Dicadangkan untuk inisialisasi pustaka run-time Microsoft C. Objek dalam grup ini dibangun terlebih dahulu.

lib
Tersedia untuk inisialisasi vendor pustaka kelas pihak ketiga. Objek dalam grup ini dibangun setelah yang ditandai sebagai compiler, tetapi sebelum yang lain.

user
Tersedia untuk setiap pengguna. Objek dalam grup ini dibuat terakhir.

nama bagian
Memungkinkan spesifikasi eksplisit dari bagian inisialisasi. Objek dalam nama bagian yang ditentukan pengguna tidak dibangun secara implisit. Namun, alamat mereka ditempatkan di bagian bernama berdasarkan nama bagian.

Nama bagian yang Anda berikan akan berisi penunjuk ke fungsi pembantu yang akan membangun objek global yang dideklarasikan setelah dalam modul tersebutpragma.

Untuk daftar nama yang tidak boleh Anda gunakan saat membuat bagian, lihat /SECTION.

nama func
Menentukan fungsi yang akan dipanggil sebagai pengganti atexit ketika program keluar. Fungsi pembantu ini juga memanggil atexit dengan penunjuk ke destruktor untuk objek global. Jika Anda menentukan pengidentifikasi fungsi dalam pragma formulir,

int __cdecl myexit (void (__cdecl *pf)(void))

maka fungsi Anda akan dipanggil alih-alih pustaka atexitrun-time C. Ini memungkinkan Anda untuk membangun daftar destruktor untuk dipanggil ketika Anda siap untuk menghancurkan objek.

Jika Anda perlu menunggak inisialisasi (misalnya, dalam DLL) Anda dapat memilih untuk menentukan nama bagian secara eksplisit. Kode Anda kemudian harus memanggil konstruktor untuk setiap objek statis.

Tidak ada tanda kutip di sekitar pengidentifikasi untuk atexit penggantian.

Objek Anda masih akan ditempatkan di bagian yang ditentukan oleh arahan lainnya XXX_segpragma .

Objek yang dideklarasikan dalam modul tidak secara otomatis diinisialisasi oleh run-time C. Kode Anda harus melakukan inisialisasi.

Secara default, init_seg bagian hanya dibaca. Jika nama bagian adalah .CRT, pengkompilasi secara diam-diam mengubah atribut menjadi baca saja, bahkan jika ditandai sebagai baca, tulis.

Anda tidak dapat menentukan init_seg lebih dari sekali dalam unit terjemahan.

Bahkan jika objek Anda tidak memiliki konstruktor yang ditentukan pengguna, satu yang secara eksplisit ditentukan dalam kode, pengkompilasi dapat menghasilkan satu untuk Anda. Misalnya, ini dapat membuat satu untuk mengikat penunjuk v-table. Jika diperlukan, kode Anda memanggil konstruktor yang dihasilkan kompilator.

Contoh

// pragma_directive_init_seg.cpp
#include <stdio.h>
#pragma warning(disable : 4075)

typedef void (__cdecl *PF)(void);
int cxpf = 0;   // number of destructors we need to call
PF pfx[200];    // pointers to destructors.

int myexit (PF pf) {
   pfx[cxpf++] = pf;
   return 0;
}

struct A {
   A() { puts("A()"); }
   ~A() { puts("~A()"); }
};

// ctor & dtor called by CRT startup code
// because this is before the pragma init_seg
A aaaa;

// The order here is important.
// Section names must be 8 characters or less.
// The sections with the same name before the $
// are merged into one section. The order that
// they are merged is determined by sorting
// the characters after the $.
// InitSegStart and InitSegEnd are used to set
// boundaries so we can find the real functions
// that we need to call for initialization.

#pragma section(".mine$a", read)
__declspec(allocate(".mine$a")) const PF InitSegStart = (PF)1;

#pragma section(".mine$z",read)
__declspec(allocate(".mine$z")) const PF InitSegEnd = (PF)1;

// The comparison for 0 is important.
// For now, each section is 256 bytes. When they
// are merged, they are padded with zeros. You
// can't depend on the section being 256 bytes, but
// you can depend on it being padded with zeros.

void InitializeObjects () {
   const PF *x = &InitSegStart;
   for (++x ; x < &InitSegEnd ; ++x)
      if (*x) (*x)();
}

void DestroyObjects () {
   while (cxpf>0) {
      --cxpf;
      (pfx[cxpf])();
   }
}

// by default, goes into a read only section
#pragma init_seg(".mine$m", myexit)

A bbbb;
A cccc;

int main () {
   InitializeObjects();
   DestroyObjects();
}
A()
A()
A()
~A()
~A()
~A()

Baca juga

Arahan Pragma dan __pragma_Pragma kata kunci