Skip to content

An array length must be a decimal number: long[QWORDS] with a const QWORDS does not parse, and byte[0x40] is 0 #3115

Closed

Description

@nicolas-maman

The length of a fixed-size array must be written as a decimal number. A module that names its sizes cannot use those names where the size matters most:

const QWORDS: int = 128 // uint64 lanes per 1024-byte block

fill(mem: long[]) {
    long[QWORDS] scratch     // error[E0100]: Expected NUMBER, got IDENTIFIER
}

struct SkeinCtx {
    ks: long[NW + 1]         // same error
}

So std writes long[128] beside const QWORDS: int = 128, and the two can drift apart. The parser also reads the number with atoi, so a hex length (byte[0x40]) is taken as 0.

Fix: an array length is an integer constant expression: a literal in any base the language accepts, a const of the same file whose value is one, or + - * / % << >> and parentheses over those. This holds in every place a length is written: local declarations, struct fields, parameters, actor state, const tables and make's array forms. A name that is not an integer constant is a compile error saying so, and so is a length that is zero or less. The reference states the rule in Array Types, and the std modules that wrote a number beside a named size use the name.

Found on #3101 (#3107, moving argon2's and skein's scratch buffers onto arrays).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions