Variable Declaration
Int i as variable declaration,
very much as in C/C++ (and Java, C#).
TypeName variableName
Some simplifications and restrictions:
- The type definition is completely on the left-hand side,
i.e. before the variable name, also for arrays and bit fields. - All variables in a multiple-variable declarations have to be of the exact same type.
Examples
Int iInt i = 0Int x, yInt x = 99, y = 199- Arrays
Int[10] highScoreTable// Array of ten integers (instead of)Int highScoreTable[10]
- Multiple-variable declarations (unlike C/C++)
Float* m, n// m and n are pointersInt& m = x, n = y// m and n are references)Float[2] p1, p2// p1 and p2 are arrays of two Float values each
- Constructors
Image image(width, height, 0.0)Image image()- is the same as
Image image, i.e. it is a variable declaration, - a function declaration would be written as
func image() -> Image.
- is the same as
- References
Complex<Float>& complexNumber = complexNumberWithOtherName
Const
const always binds to the right (contrary to C/C++).
- One can read
const intas “a constant integer”. constbinds more strongly than*and&, but less strongly than[].- So the keyword
constis always interpreted as a type qualifier to what appears immediately to its right, which can be:- a type specifier (e.g.
Float), - a pointer declarator (
*), or - a type specifier with array declarator (
Float[],Float[3], orFloat[String]).
- a type specifier (e.g.
- So the keyword
constas a type qualifier for a reference (&) is not allowed, i.e. no.Float const&const Float&is allowed, of course.
- Examples:
const Float* pointerToConstantFloatconst Float const* constantPointerToConstantFloatFloat const* constantPointerToMutableFloatconstas a type qualifier for an array declarator ([]):const Float[] constArrayOfFloatis equivalent toconst Array<Float> constArrayOfFloat.Float const[] constArrayOfFloatis equivalent toconst Array<Float> constArrayOfFloat, too. Members of a const array are always effectively const anyway.- With the array declarator syntax (
[]) it is not possible to sayArray<const Float> arrayOfConstFloat. But that does not compile anyway, because you cant assign values to an array whose element type is non-assignable. (MSVC says ‘The C++ Standard forbids containers ofconstelements becauseallocator<const T>is ill-formed.’)
const Float[3]is aconststatic array declarator, interpreted as aconststatic array of threeFloat(which effectively areconst, too).const ContactInfo[String] constMapOfContactInfoByNameis equivalent toconst Map<String, ContactInfo> constMapOfContactInfoByName.
Type Inference
with var / const:
var i = 3instead ofauto i = 3;const i = 3instead of(it is short, andconst auto i = 3;const var/ “constant variable” is a bit of a contradiction in terms.)
Not Allowed
It is a syntax error to write:
Float* m, &n- Type variations within multiple-variable declarations are not allowed.
- It has to be the exact same type.
Float*m- Whitespace between type specification and variable name is mandatory.
- TODO Probably too difficult to realize, as the lexer already removes all whitespace.
Image image { width, height, 0.0 }- No uniform / brace initialization for plain constructors, as there is no need anymore.
- There are generally no implicit narrowing conversions, e.g.
- not
,Int64->Int32 - not
,Float64->Float32
- not
- and no other unsafe integral promotions allowed:
,Int->UIntUInt->Int
- Nowhere, not in
- assignments,
- function or constructor calls,
- list initialization (with
{ }), - arithmetic expressions (integral promotions),
- mixed types in expressions,
- enums, nor
- return values.
- The most vexing parse is mitigated with the keyword
func. - Brace initialization only for constructors with
InitializerList<T>as parameter (i.e. for “list-initialization” and “copy-list-initialization”).
- There are generally no implicit narrowing conversions, e.g.
- See Misc / Mixed arithmetic and https://stackoverflow.com/a/18222927
- No uniform / brace initialization for plain constructors, as there is no need anymore.
Bit Fields
UInt32:1 signinstead of.UInt32 sign : 1- TODO Standardization of the bit field layout would be nice (LSB-first like on LittleEndian/Intel, or MSB-first like on BigEndian/Motorola),
- but IMHO there is no clear/logical/right definition (especially with LittleEndian).
- Dense packing of Int1, Int2, Int3, …, Int64 could be more straightforward anyway.