Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2026-02

Class var in record breaks pointer cast

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Hairy Pixels

Is this a bug? Adding the class var field changes prints 0 and without it prints 100 as expected. The class var is just a static field that isn't actually part of the record so how could it affect the memory layout?

type
  TMyRec = record
    class var z: UInt32;
    x, y: UInt32;
  end;
var
  r: TMyRec;
  p: pointer;
begin
  r.x := 100;
  p := @r;
  writeln(PUInt32(p)^);
end.
Martin Frb
to Hairy Pixels
Hairy Pixels wrote
Is this a bug? Adding the class var field changes prints 0 and without it prints 100 as expected. The class var is just a static field that isn't actually part of the record so how could it affect the memory layout?

A class var is (as the name suggest "not instance") not part of the instance. (instead a scoped global var).

So a pointer to the instance can not be to the memory that holds the class var data.

Show quoted text 17 lines
type   TMyRec = record     class var z: UInt32;     x, y: UInt32;   end; var   r: TMyRec;   p: pointer; begin   r.x := 100;   p := @r;   writeln(PUInt32(p)^); end.
Martin Frb
to Martin Frb
Martin Frb wrote 11 lines
On 05/02/2026 14:34, Hairy Pixels via fpc-pascal wrote: > Is this a bug? Adding the class var field changes prints 0 and > without it prints 100 as expected. The class var is just a static > field that isn't actually part of the record so how could it affect > the memory layout? A class var is (as the name suggest "not instance") not part of the instance. (instead a scoped global var). So a pointer to the instance can not be to the memory that holds the class var data.

Sorry, strike above / messed up the field names while reading. You aren't accessing "z".

My bad.

Show quoted text 21 lines
> > type >   TMyRec = record >     class var z: UInt32; >     x, y: UInt32; >   end; > > var >   r: TMyRec; >   p: pointer; > begin >   r.x := 100; >   p := @r; > >   writeln(PUInt32(p)^); > end. > _______________________________________________ fpc-pascal maillist  -  https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Martin Frb
to Martin Frb
Martin Frb wrote 8 lines
> >> >> type >>   TMyRec = record >>     class var z: UInt32; >>     x, y: UInt32; >>   end;

Ok found something...

I tried debugging, and noted that with the class var, the record had no debug info for any field.
And expecting memory did not reveal any data, if wrote to other fields.

"class var" seems to start a section, like "public type"

So all 3 fields in your example are class vars.

Try the below:

type
   TMyRec = record
     class var
        z: UInt32;
     var  // new section, normal fields // tested 3.3.1
       x, y: UInt32;
   end;
Hairy Pixels
to Martin Frb

On Feb 5, 2026 at 9:54:04 PM, Martin Frb via fpc-pascal <

Show quoted text 10 lines
wrote: type TMyRec = record class var z: UInt32; var // new section, normal fields // tested 3.3.1 x, y: UInt32; end;

oh it was a parsing issue, good find, thanks. For some reason I thought "class" could only contain one list of names.

Sven Barth
to Martin Frb: Ok found something... I tried debugging, and noted that with the class var, the record…

Martin Frb via fpc-pascal schrieb am Do.,
5. Feb. 2026, 15:54:

On 05/02/2026 15:45, Martin Frb via fpc-pascal wrote: "class var" seems to start a section, like "public type"

It not only seems so, it *is* so.

While it's not explicitly me mentioned for records it is somewhat mentioned for classes:
https://www.freepascal.org/docs-html/current/ref/refsu24.html#x74-980006.3.2

Regards,
Sven