When Const is Not Const

Recently on the Delphi Developer FB Group, this interesting post caused quite the confusion:

Enter the Debugger

With the const modifier the memory addresses are the same (pass by reference):

p1: TPoint $427CEC
p2: TPoint $427CEC

Without const, they are different (pass by value):

p1: TPoint $427CEC
p2: TPoint $19FF28

The global variable p1 has a value of 1,1.

When we use the const modifier, p2 references the same value as p1. When the value of p1 changes (to 2,2) p2 is still referencing it, hence 2,2 is returned.

Without the const modifier, p2 references a copy of p1‘s value (1,1). p2‘s copy is not modified in the method, so it returns 1,1.

Everything is behaving correctly.

Here be Dragons

There was a change introduced in Delphi Rio. With or without const, records sized 1, 2, or 4 bytes are passed as 8-bit, 16-bit, and 32bit values. They are passed by value.

TPoint is a record with two fields (2 x LongInt). It is 8 bytes long, so it passed by reference when we use the const modifier.

However, if we use the TSmallPoint record instead (with 2 x SmallInt fields) it is only 4 bytes long, and therefore passed by value. With or without the const modifier, the result is always 1,1.

This is officially documented here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s