#pragma package

From RAD Studio
Jump to: navigation, search

Go Up to Pragma Directives Overview Index

Syntax (See Pseudo-grammar)

#pragma package(smart_init)
#pragma package(smart_init, weak)

Description

#pragma package(smart_init)

The #pragma package(smart_init) ensures that packaged units are initialized in the order determined by their dependencies (included by default in package source file.) Typically, you would use the #pragma package for .cpp files that are built as packages.

Note: Do not use #pragma package(smart_init) in a header file. Doing so can result in compiler error E2177 Redeclaration of #pragma package with different arguments (C++).

This pragma affects the order of initialization of that compilation unit. For units, initialization occurs in the following order:

  1. By their "uses" dependencies, that is, if unitA depends on unitB, unitB must be initialized before unitA.
  2. The link order.
  3. Priority order within the unit.

For regular object files (those not built as units), initialization happens first according to priority order and then link order. Changing the link order of the object files changes the order in which the global object constructors get called.

The following examples show how the initialization differs between units and regular object files.

Example

Suppose you have three source files, A, B, and C, that are "smart initialized" with #pragma package(smart_init) and have functions with priority values set at 10, 20, and 30 (defined by the priority parameter of the #pragma startup). The functions are named according to their priority value and the parent source file, so the names are a10, a20, a30, b10, b20, and so on.

Here are the three programs A, B, and C:

// A.cpp
#include <stdio.h>

#ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif

void A10() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup A10 10

void A20() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup A20 20

void A30() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup A30 30
// B.cpp
#include <stdio.h>

#ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif

void B10() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup B10 10

void B20() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup B20 20

void B30() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup B30 30
// C.cpp
#include <stdio.h>

#ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif

void C10() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup C10 10

void C20() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup C20 20

void C30() {
  printf("%s() ", __FUNCTION__);
}
#pragma startup C30 30

If you build the source files as written and with USE_PACKAGE_INIT defined, the following prints out:

A10() A20() A30() B10() B20() B30() C10() C20() C30()

That is, priority is ignored and each unit has all its initialization run at once.

You get a completely different result if you build the source files without USE_PACKAGE_INIT defined. In this case, when you run the program, the following prints out:

A10() B10() C10() A20() B20() C20() A30() B30() C30()

That is, the startup prority is used.

Since all three are units, and if A uses B and C, and the link order is A, B, then C, the order of initialization is: B10() B20() B30() C10() C20() C30() A10() A20() A30()

If the above were object files, not units, the order would be: A10() B10() C10() A20() B20() C20() A30() B30() C30()

The .cpp files that use #pragma package(smart_init) also require that any #pragma link references to other object files from a .cpp file that declares #pragma package(smart_init) must be resolved by a unit. #pragma link references to nonobject files can still be resolved by libraries, and so on.

#pragma package(smart_init, weak)

The #pragma package(smart_init, weak) directive affects the way an object file is stored in package's .bpi and .bpl files. If #pragma package(smart_init, weak) appears in a unit file, the compiler omits the unit from BPLs when possible, and creates a non-packaged local copy of the unit when it is required by another application or package. A unit compiled with this directive is said to be "weakly packaged".

#pragma package(smart_init, weak) is used to eliminate conflicts among packages that may depend on the same external library.

Unit files containing the #pragma package(smart_init, weak) directive must not have global variables.

For more information about using weak packages, see Weak packaging.

See Also