Compartilhar via


Annotation Expressions

PFD supports expressions in annotations. You can use any side-effect free C expression and most side-effect free C++ expressions anywhere that an expression can be used. C++ expressions are constrained where nested classes and namespaces are involved; not all symbols will be visible.

The exact form of the expression that is permitted depends on the annotation. Some annotations require l-Values, some r-Values, and some require constant expressions.

Annotations can be built by using the following operators:

+ - +(unary) -(unary) *(multiplication) / % &(bitwise and) | && || < >   ==   !=   <=   >=   <<   >>   ^ ( )   ->   . [ ] *(dereference).  

The unary &(address-of) operator is not supported.

  • The following operands are supported: parameter names, 'this', 'return', __param(n), variables, field names. __param(n) names, the n'th (starting from 1) parameter.

  • Expressions can include most constants - C++ constants, enumerations (some symbol limitations in C++), all forms of integer constants (such as 0UL). Constants that have been defined ( #defined) can be used.

  • (static) casts and sizeof are supported.

  • Constant folding is performed. When the value of a parameter can be determined, that value is used. As in C, expressions in a Boolean context are converted to zero or nonzero.

  • The calculations are all carried out as wide signed integers and do not rely on implied truncation to a narrower word size.

  • The && and || operators do not necessarily guarantee Boolean short-circuit evaluation (nor in general is that meaningful in this context because there are no side-effects).

PFD provides for the following analysis-time functions:

  • strstr$(p1, p2**)**. This function computes the same value as the C function strstr, except that the result is the offset in string p1 where the first instance of p2 is found. If p2 is not found in p1, strstr$ returns -1. The arguments p1 and p2 can be either parameter expressions or literals. The typical use of this function is to determine whether p1 contains the constant p2. For example, the following function call determines if path contains any backslash characters:

    strstr$(path, "\\")>=0
    

    The following function call determines if path begins with "C:".

    strstr$(path, "C:")==0
    
  • macroDefined$(p1). This function determines if the string p1 (which should be a quoted string) is a symbol that is defined with #define. If p1 is not a defined symbol, the function returns 0. If p1 is a defined symbol, the function returns 1. Normally the function should be used with the macro __drv_defined(p1) so that the quoting of the symbol is correct. The annotation __drv_defined(XYZ) returns a Boolean value that indicates whether XYZ is a defined symbol in the program. Note that defined symbols can be used directly in __drv_when conditions, but using either __drv_defined(p1) or macroDefined$(p1) is the only way for __drv_when to determine whether the symbol is defined.

  • isFunctionClass$(name). This function determines if the annotated function belongs to the class that is identified by name. For more information about this function, see Function Types in Conditional Expressions.

  • isKernel$( ). This function returns TRUE when it does analysis for kernel-mode code.

  • IsDriver$() returns TRUE when it does analysis for driver-mode code. .

  • holdsResource$(name) and holdsResourceGlobal$(name**,<expression>**) work with the Nonmemory Resource Annotations and return TRUE if the particular resource is held. These are predicate forms of __drv_mustHold()/__drv_mustHoldGlobal().

Note   PFD consists of several components, not all of which support the full expression language and conditional annotations. It is very unlikely that you will encounter that limitation because of the nature of the annotations that those plug-ins support.

 

 

Send comments about this topic to Microsoft

Build date: 5/3/2011