I have been trying to define a static array with size that should be known at compile time (it\'s a constant expression). It appears that gcc cannot determine the size of th
OP's primary question is well answer here.
To address OP's higher level problem of how to use values like 0.5 or 0.25 in pre-processing, use fractional arithmetic:
#define UNIT_SPEED_LIMIT 12
// #define DISTANCE_MELEE 0.25
// use 25/100 or 1/4 or ...
#define DISTANCE_MELEE_N 1
#define DISTANCE_MELEE_D 4
// #define MOVEMENT_STEPS (unsigned)(2 * UNIT_SPEED_LIMIT / DISTANCE_MELEE)
#define MOVEMENT_STEPS (2u * UNIT_SPEED_LIMIT * DISTANCE_MELEE_D / DISTANCE_MELEE_N)
struct position (*movements)[MOVEMENT_STEPS + 1];
According to the publicly available C99 draft standard n1256, the syntax for array declaration is described by
6.7.5.2 Array declarators
2
An ordinary identifier (as defined in 6.2.3) that has a variably modified type shall have either block scope and no linkage or function prototype scope. If an identifier is declared to be an object with static storage duration, it shall not have a variable length array type.
4
If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope; 124) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.
So the expression in the []
must be an integer constant expression for the array to be declarable with static
storage duration. The standard has this to say about integer constant expressions:
6.6 Constant expressions
6
An integer constant expression 99) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.
Unfortunately, (unsigned)(2 / 0.5)
does not apply the cast immediately to a floating-point constant, but rather to an arithmetic constant expression. This does not constitute an integer constant expression, and is thus not permissible as the size of an array with static
storage duration.