Pragmas - D Programming Language
Description: D Programming Language
Keywords: D programming language

Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Forums
  - IRC
  - Community Discord
  - Wiki
  - GitHub
  - Issues
  - Get involved
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# Pragmas

Contents

1. Predefined Pragmas
   1. pragma crt_constructor
   2. pragma crt_destructor
   3. pragma inline
   4. pragma lib
   5. pragma linkerDirective
   6. pragma mangle
   7. pragma msg
   8. pragma printf
   9. pragma scanf
   10. pragma startaddress
2. Vendor Specific Pragmas

    Pragma:
        pragma ( Identifier )
        pragma ( Identifier , ArgumentList )

Pragmas are a way to pass special information to the compiler and to add vendor specific extensions to D. Pragmas can be used by themselves terminated with a ‘;’, they can influence a statement, a block of statements, a declaration, or a block of declarations.

Pragmas can appear as either declarations, Pragma DeclarationBlock, or as statements, PragmaStatement.

    pragma(ident);        // just by itself

    pragma(ident) declaration; // influence one declaration

    pragma(ident): // influence subsequent declarations
        declaration;
        declaration;

    pragma(ident)   // influence block of declarations
    {
        declaration;
        declaration;
    }

    pragma(ident) statement; // influence one statement

    pragma(ident)   // influence block of statements
    {
        statement;
        statement;
    }

The kind of pragma it is determined by the Identifier. ArgumentList is a comma-separated list of AssignExpressions. The AssignExpressions must be parsable as expressions, but their meaning is up to the individual pragma semantics.

## Predefined Pragmas

All implementations must support these, even if by just ignoring them:

- pragma crt_constructor
- pragma crt_destructor
- pragma inline
- pragma lib
- pragma linkerDirective
- pragma mangle
- pragma msg
- pragma printf
- pragma scanf
- pragma startaddress

Implementation Defined: An implementation may ignore these pragmas.

### pragma crt_constructor

This pragma must directly precede an extern(C) function declaration that must take no argument, even default ones. The function this pragma applies to will be inserted in .init_array or .ctors, depending on the target and compiler implementation. It is equivalent to GCC's __attribute__((constructor)).

    __gshared int initCount;

    pragma(crt_constructor)
    extern(C) void initializer() { initCount += 1; }

It is useful for system programming and interfacing with C/C++, for example to allow for initialization of the runtime when loading a DSO, or as a simple replacement for shared static this in betterC mode.

A module may contain any number of functions annotated with crt_constructor. The order in which functions are called is undefined and shouldn't be relied upon. A function can be annotated as both crt_constructor and crt_destructor (see below). The runtime is not initialized when the function is called. This pragma does not take any argument and can only be applied to a single declaration, so using them in an AttributeSpecifier is disallowed.

crt_constructor and crt_destructor were implemented in v2.078.0 (2018-01-01). Some compilers exposed non-standard, compiler-specific mechanism before.

### pragma crt_destructor

Similarly, pragma(crt_destructor) must also directly precede an extern(C) function declaration that must take no argument, even default ones. The function this pragma applies to will be inserted in .fini_array or .dtors, depending on the target and compiler implementation. It is equivalent to GCC's __attribute__((destructor)).

    __gshared int initCount;

    pragma(crt_constructor)
    extern(C) void initialize() { initCount += 1; }

    pragma(crt_destructor)
    extern(C) void deinitialize() { initCount -= 1; }

    pragma(crt_constructor)
    pragma(crt_destructor)
    extern(C) void innuendo() { printf("Inside a constructor... Or destructor?\n"); }

The runtime might have been terminated and not be usable anymore when the destructors are called. Otherwise, usage and requirements of crt_destructor are similar to those of crt_constructor.

### pragma inline

Affects whether functions are inlined or not. If at the declaration level, it affects the functions declared in the block it controls. If inside a function, it affects the function it is enclosed by.

It takes three forms:

1.     pragma(inline)

   Sets the behavior to match the implementation's default behavior.

2.     pragma(inline, false)

   Functions are never inlined.

3.     pragma(inline, true)

   Always inline the functions.

There can be only zero or one AssignExpressions. If one is there, it must be true, false, or an integer value. An integer value is implicitly converted to a bool.

If there are multiple pragma inlines in a function, the lexically last one takes effect.

    pragma(inline):
    int foo(int x) // foo() is never inlined
    {
        pragma(inline, true);
        ++x;
        pragma(inline, false); // supercedes the others
        return x + 3;
    }

Implementation Defined:

1. The default inline behavior is typically selectable with a compiler switch such as -inline.
2. Whether a particular function can be inlined or not is implementation defined.
3. What happens for pragma(inline, true) if the function cannot be inlined. An error message is typical.

### pragma lib

There must be one AssignExpression and it must evaluate at compile time to a string literal.

    pragma(lib, "foo.lib");

Implementation Defined: Typically, the string literal specifies the file name of a library file. This name is inserted into the generated object file, or otherwise is passed to the linker, so the linker automatically links in that library.

### pragma linkerDirective

There must be one AssignExpression and it must evaluate at compile time to a string literal.

    pragma(linkerDirective, "/FAILIFMISMATCH:_ITERATOR_DEBUG_LEVEL=2");

Implementation Defined:

The string literal specifies a linker directive to be embedded in the generated object file.

Linker directives are only supported for MS-COFF output.

### pragma mangle

Overrides the default mangling for a symbol.

There must be one AssignExpression and it must evaluate at compile time to a string literal.

Implementation Defined: On macOS and Win32, an extra underscore (_) is prepended to the string since 2.079, as is done by the C/C++ toolchain. This allows using the same pragma(mangle) for all compatible (POSIX in one case, win64 in another) platforms instead of having to special-case.
Implementation Defined: It's only effective when the symbol is a function declaration or a variable declaration. For example this allows linking to a symbol which is a D keyword, which would normally be disallowed as a symbol name:

    pragma(mangle, "body")
    extern(C) void body_func();

### pragma msg

Constructs a message from the ArgumentList.

    pragma(msg, "compiling...", 1, 1.0);

Implementation Defined: The arguments are typically presented to the user during compilation, such as by printing them to the standard error stream.

### pragma printf

pragma(printf) specifies that a function declaration is a printf-like function, meaning it is an extern (C) or extern (C++) function with a format parameter accepting a pointer to a 0-terminated char string conforming to the C99 Standard 7.19.6.1, immediately followed by either a ... variadic argument list or a parameter of type va_list as the last parameter.

If the format argument is a string literal, it is verified to be a valid format string per the C99 Standard. If the format parameter is followed by ..., the number and types of the variadic arguments are checked against the format string.

Diagnosed incompatibilities are:

- incompatible sizes which may cause argument misalignment
- deferencing arguments that are not pointers
- insufficient number of arguments
- struct arguments
- array and slice arguments
- non-pointer arguments to s specifier
- non-standard formats
- undefined behavior per C99

Per the C99 Standard, extra arguments are ignored.

Ignored mismatches are:

- sign mismatches, such as printing an int with a %u format
- integral promotion mismatches, where the format specifies a smaller integral type than int or uint, such as printing a short with the %d format rather than %hd

    printf("%k\n", value); // error: non-Standard format k
    printf("%d\n");        // error: not enough arguments
    printf("%d\n", 1, 2);  // ok, extra arguments ignored

Best Practices: In order to use non-Standard printf/scanf formats, an easy workaround is:

    const format = "%k\n";
    printf(format.ptr, value);  // no error

Best Practices: Most of the errors detected are portability issues. For instance,

    string s;
    printf("%.*s\n", s.length, s.ptr);
    printf("%d\n", s.sizeof);
    ulong u;
    scanf("%lld%*c\n", &u);

should be replaced with:

    string s;
    printf("%.*s\n", cast(int) s.length, s.ptr);
    printf("%zd\n", s.sizeof);
    ulong u;
    scanf("%llu%*c\n", &u);

pragma(printf) applied to declarations that are not functions are ignored. In particular, it has no effect on the declaration of a pointer to function type.

### pragma scanf

pragma(scanf) specifies that a function declaration is a scanf-like function, meaning it is an extern (C) or extern (C++) function with a format parameter accepting a pointer to a 0-terminated char string conforming to the C99 Standard 7.19.6.2, immediately followed by either a ... variadic argument list or a parameter of type va_list as the last parameter.

If the format argument is a string literal, it is verified to be a valid format string per the C99 Standard. If the format parameter is followed by ..., the number and types of the variadic arguments are checked against the format string.

Diagnosed incompatibilities are:

- argument is not a pointer to the format specified type
- insufficient number of arguments
- non-standard formats
- undefined behavior per C99

Per the C99 Standard, extra arguments are ignored.

pragma(scanf) applied to declarations that are not functions are ignored. In particular, it has no effect on the declaration of a pointer to function type.

### pragma startaddress

There must be one AssignExpression and it must evaluate at compile time to a function symbol.

Implementation Defined: The function symbol specifies the start address for the program. The symbol is inserted into the object file or is otherwise presented to the linker to set the start address. This is not normally used for application level programming, but is for specialized systems work. For applications code, the start address is taken care of by the runtime library.

    void foo() { ... }
    pragma(startaddress, foo);

## Vendor Specific Pragmas

Vendor specific pragma Identifiers can be defined if they are prefixed by the vendor's trademarked name, in a similar manner to version identifiers:

    pragma(DigitalMars_extension) { ... }

Implementations must diagnose an error for unrecognized Pragmas, even if they are vendor specific ones.

Implementation Defined: Vendor specific pragmas.
Best Practices: vendor specific pragmas should be wrapped in version statements

    version (DigitalMars)
    {
        pragma(DigitalMars_extension)
        {   ... }
    }

Attributes
Expressions
Copyright © 1999-2020 by the D Language Foundation | Page generated by Ddoc on Sat Aug 15 09:59:34 2020