AttributeSpecifier: Attribute : Attribute DeclarationBlock AttributeElseSpecifier: AttributeElse : AttributeElse DeclarationBlock AttributeElse DeclarationBlock else DeclarationBlock Attribute: LinkageAttribute AlignAttribute deprecated private protected public export static final override abstract const AttributeElse: DebugAttribute VersionAttribute DeclarationBlock Declaration ; { Declarations }Attributes are a way to modify one or more declarations. The general forms are:
attribute declaration; affects the declaration attribute: affects all declarations until the next } declaration; declaration; ... attribute affects all declarations in the block { declaration; declaration; ... }For attributes with an optional else clause:
attribute declaration; else declaration; attribute affects all declarations in the block { declaration; declaration; ... } else { declaration; declaration; ... }
LinkageAttribute: extern extern ( LinkageType ) LinkageType: C D Windows PascalD provides an easy way to call C functions and operating system API functions, as compatibility with both is essential. The LinkageType is case sensitive, and is meant to be extensible by the implementation (they are not keywords). C and D must be supplied, the others are what makes sense for the implementation. Implementation Note: for Win32 platforms, Windows and Pascal should exist.
C function calling conventions are specified by:
extern (C): int foo(); call foo() with C conventionsD conventions are:
extern (D):or:
extern:Windows API conventions are:
extern (Windows): void *VirtualAlloc( void *lpAddress, uint dwSize, uint flAllocationType, uint flProtect );
DebugAttribute: debug debug ( Integer ) debug ( Identifier )Two versions of programs are commonly built, a release build and a debug build. The debug build includes extra error checking code, test harnesses, pretty-printing code, etc. The debug attribute conditionally compiles in code:
class Foo { int a, b; debug: int flag; }Conditional Compilation means that if the code is not compiled in, it still must be syntactically correct, but no semantic checking or processing is done on it. No symbols are defined, no typechecking is done, no code is generated, no imports are imported. Various different debug builds can be built with a parameter to debug:
debug(n) { } // add in debug code if debug level is <= n debug(identifier) { } // add in debug code if debug keyword is identifierThese are presumably set by the command line as -debug=n and -debug=identifier.
See also the Debug Statement.
VersionAttribute: version ( Integer ) version ( Identifier )The version attribute is very similar to the debug attribute, and in many ways is functionally interchangable with it. The purpose of it, however, is different. While debug is for building debugging versions of a program, version is for using the same source to build multiple release versions.
For instance, there may be a full version as opposed to a demo version:
class Foo { int a, b; version(full) { int extrafunctionality() { ... return 1; // extra functionality is supported } } else // demo { int extrafunctionality() { return 0; // extra functionality is not supported } } }Various different version builds can be built with a parameter to version:
version(n) { } // add in version code if version level is >= n version(identifier) { } // add in version code if version keyword is identifierThese are presumably set by the command line as -version=n and -version=identifier.
See also the Version Specification, Version Statement and Predefined Versions.
AlignAttribute: align align ( Integer )Specifies the alignment of struct members. align by itself sets it to the default, which matches the default member alignment of the companion C compiler. Integer specifies the alignment which matches the behavior of the companion C compiler when non-default alignments are used. A value of 1 means that no alignment is done; members are packed together.
deprecated { void oldFoo(); }Implementation Note: The compiler should have a switch specifying if deprecated declarations should be compiled with out complaint or not.
Private means that only members of the enclosing class can access the member. Private members cannot be overridden. Private module members are equivalent to static declarations in C programs.
Protected means that only members of the enclosing class or any classes derived from that class can access the member. Protected module members are illegal.
Public means that any code within the executable can access the member.
Export means that any code outside the executable can access the member. Export is analogous to exporting definitions from a DLL.
constThe const attribute declares constants that can be evaluated at compile time. For example:
const int foo = 7; const { double bar = foo + 6; }
overrideThe override attribute applies to virtual functions. It means that the function must override a function with the same name and parameters in a base class. The override attribute is useful for catching errors when a base class's member function gets its parameters changed, and all derived classes need to have their overriding functions updated.
class Foo { int bar(); int abc(int x); } class Foo2 : Foo { override { int bar(char c); // error, no bar(char) in Foo int abc(int x); // ok } }