2. Declarations

Syntax Summary
[aligned[(expression)]] type[(expression | map)][*] name [= expression];

2.1 General

Regular variable declarations can be used in Flavor in the same way as in C++ and Java.

As Flavor follows a declarative approach, constant variable declarations with specified values are allowed everywhere (there is no constructor to set the initial values). This means that the declaration ‘const int a=1;’ is valid anywhere (not just in global scope). The two major differences are the declaration of parsable variables (discussed below) and arrays.

2.2 Parsable Variables

Parsable variables are the core of Flavor’s design; it is the proper definition of these variables that defines the bitstream syntax.

Parsable variables include a parse length specification immediately after their type declaration, as shown in the following example.

    unsigned int(5) a;

length can be an integer constant, a non-constant variable of type compatible to int, or a map with the same type as the variable. This means that the parse length of a variable can be controlled by another variable.

Bit and byte ordering is big-endian, i.e., the most significant bit and byte come first.

In addition to the parse length specification, parsable variables (including parsable classes) can also have the modifier aligned. This signifies that the variable begins at the next integer multiple boundary of the length specified within the alignment expression. If this length is omitted, an alignment size of 8 is assumed (byte boundary). Only multiples of 8 are allowed. For parsing, any intermediate bits are ignored, while for output bitstream generation the bitstream is padded with zeros.

Parsable variables cannot be assigned to. This ensures that the syntax is preserved regardless if we are performing an input or output operation. However, parsable variables can be redeclared, as long as their type remains the same, only the parse size is changed, and the original declaration was not as a const. This allows one to select the parse size depending on the context (see Expressions and Statements). In addition, the obey special scoping rules (see Scoping Rules.

In general, the parse size expression must be a non-negative value. The special value 0 can be used when, depending on the bitstream context, a variable is not present in the bitstream but obtains a default value. In this case no bits will be parsed or generated, however the semantics of the declaration will be preserved.

Finally, variables of type float, double, and long double are only allowed to have a parse size equal to the fixed size that their standard representation requires (32 and 64 bits).

2.3 Look-Ahead Parsing

In several instances it is desirable to examine the immediately following bits in the bitstream, without actually removing the bits. To support this behavior, a '*' character can be placed after the parse size parentheses to modify the parse size semantics. Note that for bitstream output purposes this has no effect. Example:

    unsigned int(5)* a;

2.4 Parsable Variables with Expected Values

Very often, certain parsable variables in the syntax have to have specific values (markers, start codes, reserved bits, etc.). These are specified as initialization values for parsable variables. Example:

    aligned unsigned int(5) a = 'a';

The keyword const may be prepended in the declaration, to indicate that the parsable variable will have this constant value and, as a result, cannot be redeclared.

As both parse size and initial value can be arbitrary expressions, we should note that the order of evaluation is parse expression first, followed by the initializing expression.