In C++, any line with a leading # is taken as a Preprocessing Directive, unless the # is within a string literal, in a character constant, or embedded in a comment. The initial # can be preceded or followed by whitespace (excluding new lines). If you use the preprocessing directive #pragma, you can set compiler directives in your source code, without interfering with other compilers that also support #pragma. When you create an application in a professional C++ Editor, generally they automatically add some pragma directives to your code. These may be resources and packages for the application. You may use some more directives too.
C++Builder supports many #pragma directives, some of pragma directives support both classic compiler and CLANG compiler. In this article we will give some brief information about these directives. First, lest learn what is is # preprocessor directive,
Table of Contents
What is the # preprocessor directive?
Preprocessor directives are usually placed at the beginning of your source code, but they can legally appear at any point in a program. The preprocessor detects preprocessor directives (also known as control lines) and parses the tokens embedded in them.
Any line with a leading # is taken as a preprocessing directive, unless the # is within a string literal, in a character constant, or embedded in a comment. The initial # can be preceded or followed by whitespace (excluding new lines). #include
, #define
, #pragma
are some of these preprocessor directive examples.
Preprocessor directives are usually placed at the beginning of your source code, but they can legally appear at any point in a program. The preprocessor detects preprocessor directives (also known as control lines) and parses the tokens embedded in them.
What is the #pragma pragma directive in C++?
With #pragma, you can set compiler directives in your source code, without interfering with other compilers that also support #pragma. If the compiler doesn’t recognize directive-name, it ignores the #pragma directive without any error or warning message.
Here is the syntax for the #pragma directive,
1 |
#pragma <directive-name> |
C++Builder supports many #pragma directives, some of pragma directives support both classic compiler and CLANG compiler, these are;
What is the “#pragma package” pragma directive in C++?
#pragma package controls the initialization order of packages and other aspects related to packages. Here are two syntax examples,
1 2 |
#pragma package(smart_init) #pragma package(smart_init, weak) |
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:
- By their “uses” dependencies, that is, if unitA depends on unitB, unitB must be initialized before unitA.
- The link order.
- 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.
1 |
#pragma package(smart_init) |
If you want more examples, please check here https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Pragma_package
What is the “#pragma resource” pragma directive in C++?
#pragma resource emits a comment record that instructs the linker to mark the file as a form unit. This pragma causes the file to be marked as a form unit and requires matching .dfm
and header files. All such files are managed by the IDE.
If your form requires any variables, they must be declared immediately after the pragma resource is used. The declarations must be of the form:
1 |
#pragma resource "*.dfm" |
What is the “#pragma comment” pragma directive in C++?
#pragma comment syntax, writes a comment record in the object file. This can include linking to a library module. See Auto Linking for more information.
1 |
#pragma comment( comment-type [ , "comment-string" ] ) |
The comment
directive lets you write a comment record into an output file. The comment type can be one of the following values:
comment-type | Explanation |
---|---|
exestr | The linker writes a string into an .obj file. Your specified string is placed in the executable file. Such a string is never loaded into memory but can be found in the executable file by use of a suitable file search utility. |
lib | Writes a comment record into an .obj file. A library module that is not specified in the linker’s response file can be specified by the comment LIB directive. The linker includes the library module name specified in the string as the last library. Multiple modules can be named and linked in the order in which they are named. |
user | The compiler writes a string into the .obj file. The linker ignores the specified string. |
Here is an #pragma comment example,
1 |
#pragma comment(user, "comment here") |
What is the “#pragma link” pragma directive in C++?
#pragma link instructs the linker to link the file into an executable file. See Auto Linking for more information.
The #pragma link
directive instructs the linker to link the specified file into an executable file. Here is the Syntax for this,
1 |
#pragma link "[path]modulename[.ext]" |
Use the path argument to specify a directory. By default, the linker searches for modulename in the local directory and in any path specified by the -L option of the linker. Do not specify the file extension (.ext
) of modulename, as long as you are using default file types. The linkers assume the following default values for the file extension (.ext
) of modulename:
.obj
extension for BCC32.o
extension for Clang-enhanced C++ compilers
So if you omit the .ext
, then the correct extension is automatically used according to your current target platform.
Here is an example to link a “module1.o” module,
1 |
#pragma link "module1" |
What does the pragma directive “#pragma message” mean in C++?
#pragma message, prints the specified message at compile time. Use #pragma message
to specify a user-defined message within your program code.
Here is the Syntax;
1 2 |
#pragma message ("text" ["text"["text" ...]]) #pragma message text |
The first form requires that the text consist of one or more string constants, and the message must be enclosed in parentheses (this form is compatible with Microsoft C). This form will output the constant contained between the double quotation marks regardless of whether it is a macro or not.
The second form uses the text following the #pragma for the text of the warning message. With this form of the #pragma, any macro references are expanded before the message is displayed.
The third form will output the macro-expanded value of text following the #pragma,if it is #defined. If it is not #defined, you’ll get an ill-formed pragma warning.
User-defined messages are displayed as messages, not warnings. Display of user-defined messages is on by default and can be turned on or off with the Show Messages option. This option corresponds to the compiler’s -wmsg switch.
Messages are only displayed in the IDE if Show general messages is checked on the C++ Project Properties under Project > Options > Project Propertes.
1 |
#pragma message("Hello") |
In compilation, the Message window will show this as a warning below,
1 |
[bcc32c Warning] Unit1.cpp(11): Hello |
What is the “#pragma startup” pragma directive in C++?
#pragma startup indicates a function to be run on program startup (before main). #pragma startup
and #pragma exit
pragmas allow the program to specify function(s) that should be called either upon program startup (before the main function is called) or program exit (just before the program terminates through _exit).
Here is the syntax of #pragma startup,
1 |
#pragma startup FUNC [NN] |
The specified function name must be a previously declared function taking no arguments and returning void; in other words, it should be declared as:
1 |
void myfunc(void); |
Then the #pragma
would be:
1 |
#pragma startup myfunc |
What is the “#pragma exit” pragma directive in C++?
#pragma exit indicates a function to be run on program exit (before _exit).
Here is the syntax of #pragma exit
,
1 |
#pragma exit FUNC [NN] |
How do I specify the priority of different pragma directives in C++?
The optional priority parameter (NN
) should be an integer in the range from 64 through 255:
- The highest priority is 0.
- Functions with higher priorities are called first at startup and last at exit.
- If you do not specify a priority, it defaults to 100 for both BCC32 and Clang-enhanced C++ compilers.
Warning: Do not use priority values less than 64 with BCC32. Priorities from 0 through 63 are reserved for RTL startup and shutdown mechanisms. The exception for Clang-enhanced C++ compilers is described in the text below.
What is the Unit Initialization Order in applications built with Clang-enhanced C++ compilers?
Note: Unit initialization order should take priority over #pragma startup
order, but this is currently not implemented for Clang-enhanced C++ compilers.
Clang-enhanced C++ compilers do not use unit initialization order, and therefore exit routines that are run without a priority specification close before the main form closes. If you are using Clang-enhanced C++ compilers, you must specify the #pragma exit
routine with priority 30 in order to guarantee that the exit routine runs after __ExitVCL (and to match the behavior of BCC32). For example:
1 |
#pragma exit myfunc 30 |
1 |
#pragma exit FUNC [NN] |
C++Builder supports many #pragma directives, some of pragma directives support both classic compiler and CLANG compiler.
The full list can be found in #pragma Directives Overview Index.
C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.