Поделиться через


init_seg

Конкретные C++

Задает раздел ключевого слова или Кода, который влияет на порядок, в котором выполняется Код запуска.

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

Заметки

Смысл терминов сегмент и раздел заменим в этом разделе.

Поскольку инициализация глобальных статических объектов может включать выполнение кода необходимо указать ключевое слово, которое определяет, когда объекты для построения.Особенно важно использовать init_seg директива pragma в разделе " библиотеки динамической компоновки (DLL) или библиотеках требует инициализации.

Параметры init_seg директива pragma включают:

  • компилятор
    Зарезервировано для инициализации библиотеки времени выполнения c (Майкрософт).Объекты в этой группе выполняется первым.

  • lib
    Доступный для сторонних поставщиков инициализаций библиотеки классов.Объекты в этой группе создаются после этого, помеченных как компилятор но перед любыми другими.

  • пользователь
    Доступный для любого пользователя.Объекты в этой группе выполняется последним.

  • раздел-имя
    Разрешает точная спецификация раздела инициализации.Пользователь-определенные объекты раздел-имя неявно не построение; однако их адреса помещаются в разделе под названием by раздел-имя.

    Имя раздела предоставляемые содержит указатели на функции помощника, построят глобальные объекты, объявленные в этом модуле после прагмы.

    Список имен не следует использовать при создании, см. раздел. /SECTION.

  • функциональн-имя
    Определяет функцию, которую необходимо вызвать вместо atexit если выйти из программы.Вспомогательная также вызовы этой функции atexit с указателем на деструктора для глобального объекта.Если указать идентификатор функции в прагме формы,

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

    затем функция будет вызываться вместо библиотеки времени выполнения C atexit.Это позволяет создавать список деструкторов которым будет вызываться, когда можно удалить объекты.

Если нужно отложить инициализация (например, в библиотеке DLL) можно выбрать для указания имени раздела явным образом.Затем следует вызвать конструктор для каждого статического объекта.

Нет кавычек вокруг идентификатора atexit замена.

Объекты по-прежнему будут помещены в разделах заданных другими прагмами XXX_seg.

Объекты, объявленные в модуле автоматически не инициализируются средой выполнения c.Вам самостоятельно, что необходимо сделать.

По умолчанию init_seg разделы доступны только для чтения.Если имя раздела .CRT, то компилятор автоматически изменяет атрибут только для чтения, даже если он помечен как доступный для чтения и записи.

Нельзя задавать init_seg более одного раза в переводе.

Даже если объект не имеет определяемый пользователем конструктор, конструктор не явно заданный в Коде, компилятор может создать один (например привязки v-таблицы указатели).Поэтому Код вызова конструктора компилятором.

Пример

// 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();
}
  

См. также

Ссылки

Директивы pragma и ключевое слово __Pragma