PragmaDeclaration:Pragma;PragmaDeclarationBlockPragmaStatement:Pragma;PragmaNoScopeStatementPragma:pragma(Identifier)pragma(Identifier,ArgumentList)
Pragmas pass special information to the implementation and can add vendor specific extensions. Pragmas can be used by themselves terminated with a;, and can apply to a statement, a block of statements, a declaration, or a block of declarations.
Pragmas can be either aPragmaDeclaration or aPragmaStatement.
pragma(ident);// just by itselfpragma(ident) declaration;// influence one declarationpragma(ident):// influence subsequent declarations declaration; declaration;pragma(ident)// influence block of declarations{ declaration; declaration;}pragma(ident) statement;// influence one statementpragma(ident)// influence block of statements{ statement; statement;}
The kind of pragma it is determined by theIdentifier.ArgumentList is a comma-separated list ofAssignExpressions. TheAssignExpressions must be parsable as expressions, but their meaning is up to the individual pragma semantics.
All implementations must support these, even if by just ignoring them:
Annotates a function so it is run after the C runtime library is initialized and before the D runtime library is initialized.
The function must:
__gsharedint initCount;pragma(crt_constructor)extern(C)void initializer() { initCount += 1; }
No arguments to the pragma are allowed.
A function may be annotated with bothpragma(crt_constructor) andpragma(crt_destructor).
Annotating declarations other than function definitions has no effect.
Annotating a struct or class definition does not affect the members of the aggregate.
A function that is annotated withpragma(crt_constructor) may initializeconst orimmutable variables.
pragma(crt_destructor) works the same aspragma(crt_constructor) except:
__gsharedint 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"); }
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 two forms:
pragma(inline) Sets the behavior to match the implementation's default behavior.pragma(inline, AssignExpression) TheAssignExpression is evaluated and must have a type that can be converted to a boolean. If the result is false the functions are never inlined, otherwise they are always inlined.More than oneAssignExpression is not allowed.
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 othersreturn x + 3;}
There must be oneAssignExpression and it must evaluate at compile time to a string literal.
pragma(lib,"foo.lib");
There must be oneAssignExpression and it must evaluate at compile time to a string literal.
pragma(linkerDirective,"/FAILIFMISMATCH:_ITERATOR_DEBUG_LEVEL=2");
Overrides the default mangling for a symbol.
For variables and functions there must be oneAssignExpression and it must evaluate at compile time to a string literal. For aggregates there may be one or twoAssignExpressions, one of which must evaluate at compile time to a string literal and one which must evaluate to a symbol. If that symbol is aTemplateInstance, the aggregate is treated as a template that has the signature and arguments of theTemplateInstance. The identifier of the symbol is used when no string is supplied. Both arguments may be used used when an aggregate's name is a D keyword.
It only applies to function and variable symbols. Other symbols are ignored.
pragma(mangle,"body")extern(C)void body_func();pragma(mangle,"function")extern(C++)struct _function {}template ScopeClass(C){pragma(mangle, C)struct ScopeClass {align(__traits(classInstanceAlignment, C))void[__traits(classInstanceSize, C)] buffer; }}extern(C++){class MyClassA(T) {}void func(ref ScopeClass!(MyClassA!int));// mangles as MyClass<int>&}
EachAssignExpression is evaluated at compile time and then all are combined into a message.
pragma(msg,"compiling...", 6, 1.0);// prints "compiling...61.0" at compile time
staticif (kilroy)pragma(msg,"Kilroy was here");elsepragma(msg,"Kilroy got lost");
pragma(printf) specifies that a function declaration is a printf-like function, meaning it is anextern (C) orextern (C++) function with aformat parameter accepting a pointer to a 0-terminatedchar string conforming to the C99 Standard 7.19.6.1, immediately followed by either a... variadic argument list or a parameter of typeva_list as the last parameter.
If theformat argument is a string literal, it is verified to be a valid format string per the C99 Standard. If theformat parameter is followed by..., the number and types of the variadic arguments are checked against the format string.
Diagnosed incompatibilities are:
Per the C99 Standard, extra arguments are ignored.
Ignored mismatches are:
printf("%k\n", value);// error: non-Standard format kprintf("%d\n");// error: not enough argumentsprintf("%d\n", 1, 2);// ok, extra arguments ignored
const format ="%k\n";printf(format.ptr, value);// no error
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) specifies that a function declaration is a scanf-like function, meaning it is anextern (C) orextern (C++) function with aformat parameter accepting a pointer to a 0-terminatedchar string conforming to the C99 Standard 7.19.6.2, immediately followed by either a... variadic argument list or a parameter of typeva_list as the last parameter.
If theformat argument is a string literal, it is verified to be a valid format string per the C99 Standard. If theformat parameter is followed by..., the number and types of the variadic arguments are checked against the format string.
Diagnosed incompatibilities are:
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.
There must be oneAssignExpression and it must evaluate at compile time to a function symbol.
void foo() { ... }pragma(startaddress, foo);
Vendor specific pragmaIdentifiers 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 unrecognizedPragmas, even if they are vendor specific ones.
version (DigitalMars){pragma(DigitalMars_extension) { ... }}