[Oberon] Bit-fiddling: SETs and type casts in Oberon-07

thutt at harp-project.com thutt at harp-project.com
Tue Aug 9 05:16:29 CEST 2022

Hans Klaver writes:
 > Chris, Jörg and Florian,
 > Thanks for your answers. Now it makes more sense to me.
 > I looked into these matters a bit more.
 > It appears that Wirth's OR compiler always allows casts of 'scalar'
 > types (here meaning all Oberon basic types) with SYSTEM.VAL to a
 > type of the same or smaller SYSTEM.SIZE (narrowing casts), without
 > warning. Widening casts (to a type with larger SYSTEM.SIZE) are
 > only possible via cast to BYTE and INTEGER.
 > I suppose this is (as Florian wrote) because widening casts lead to
 > 'undefined behaviour'. Well, I think the behaviour in cases of
 > SYSTEM.VAL(SET, v) is only partially undefined: the part of the SET
 > one is interested in (elements 0 .. 8*SYSTEM.SIZE(v)-1) is quite
 > well defined as long as it is guaranteed that element 0 of the SET
 > is the least significant bit of the variable; the undefined part,
 > the elements > 8*SYSTEM.SIZE(v)-1, should just be disregarded.

The SYSTEM.VAL built-in is non-portable and implementation defined.
So, it's behavior is expected to differ from compiler to compiler.  In
the older compilers (not Oberon-07), SYSTEM.VAL was essentually a
'reinterpret cast'.  It would simply temporarily change the type of
the second argument to that of the first argument.

 > The other two Oberon-07 compilers I checked (Astrobe for Cortex-M3
 > and OBNC) allow all casts of the basic types to and from each
 > other, narrowing or widening; the Astrobe compiler gives a warning
 > 'type cast !' with any use of SYSTEM.VAL.
 > Chris wrote:
 > > The Oberon-07 report states:
 > >
 > > EXCL(v, x) is equivalent to v := v - {x}.  (* where v is a variable not an expression *)
 > >
 > > Hence trying to write EXCL(SYSTEM.VAL(SET, ch), 5) would be equivalent to writing:
 > >
 > > SYSTEM.VAL(SET, ch) := SYSTEM.VAL(SET, ch) - {5}
 > >
 > > To me, that is as wrong as trying to write something like:
 > >
 > > ORD(ch) := ORD(ch) + 1
 > >
 > > or INC(ORD(ch))


 > Concerning this I found out that only OBNC requires a variable as
 > first parameter of EXCL and INCL, and disallows SYSTEM.VAL in its
 > place; Wirth's OR and the Astrobe compiler have no problem with
 > SYSTEM.VAL as first parameter of these procedures. So for instance
 > they accept the following (Astrobe with a warning 'type cast !'):
 >   VAR i: INTEGER;
 >   ...
 >   EXCL(SYSTEM.VAL(SET, i), 5)
 >   RETURN i
 > This is in accordance with the language report: there it says that
 > SYSTEM.VAL has the function of 'identity' (earlier described as 'x
 > interpreted as of type T'); use of this function here can be
 > equated with use of a variable.

I suspect this works because the type is being changed temporarily for
the expression.  It's still a variable, but the type is now 'SET'.

 > So I think that OBNC is a bit too restrictive in disallowing
 > SYSTEM.VAL as first parameter of EXCL and INCL.

The use of SYSTEM.VAL is non-portable and the behavior is allowed to
vary from compiler to compiler.

Pickled beets.  Pickled beaks.  What's the difference?

More information about the Oberon mailing list