Sign in Join

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

Mailing lists / fpc-pascal / 2008-02

Empty record inside another record ?

21 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

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

Skybuck Flying

To me it seems like some kind of trick, to extend a empty record field, functions as a sort of offset/label/pointer if you will to the new fields that will will be extended to the record by simply allocating more memory then the size of the record.

Then this "label"/"field" can be used as a sort of offset, by typecasting it to some extension record type.

Could be pretty handy, quite impressive trick.

However, is it safe to use ?

I cannot find anything in the documentation about this ?

Seems to be an old trick as well.

Gonna copy this stuff and ask on free pascal compiler list, maybe they know something about this ;) I wonder if free pascal supports this trick as well ;)

Bye,
Skybuck.

"Skybuck Flying" wrote in message

Show quoted text 20 lines
Hello, What's going on here: type TsomeRecord = record SomeField : integer; SomeEmptyRecord : record end; end; How can SomeEmptyRecord be usefully used ? What is it ? SizeOf(TsomeRecord) returns 4, kinda weird ?! Bye, Skybuck.

Reply by email

Daniël Mantione
to Skybuck Flying

Op Fri, 15 Feb 2008, schreef Skybuck Flying:

Show quoted text 12 lines
To me it seems like some kind of trick, to extend a record at runtime. The empty record field, functions as a sort of offset/label/pointer if you will to the new fields that will will be extended to the record by simply allocating more memory then the size of the record. Then this "label"/"field" can be used as a sort of offset, by typecasting it to some extension record type. Could be pretty handy, quite impressive trick. However, is it safe to use ?

Empty records are valid Pascal.

I cannot find anything in the documentation about this ?

Nothing in the documentation says it is forbidden either. The reason it is not explicetely mentioned is because there exists a much better method, objects:

type  base_structure=object
         field1:byte;
       end;
       extended_structure=object(base_structure)
         field2:byte;
       end;

Daniël

Reply by email

Skybuck Flying
to Daniël Mantione

What's the benefit of using objects ?

One drawback of objects already discovered:

Objects cannot have the same field identifiers.

A problem that does not exist with records, and empty records.

// object example, pointers and typecasts still necessary.
program Project1;
{$APPTYPE CONSOLE}
uses
  SysUtils;
type
 PethernetHeader = ^TethernetHeader;
 TethernetHeader = object
  SomeFields1 : packed array[0..13] of byte;
 end;
 PipHeaderVersion4 = ^TipHeaderVersion4;
 TipHeaderVersion4 = object(TethernetHeader)
  SomeFields2 : packed array[0..19] of byte; // first problem, identifier
redeclared, numbers used to fix it.
 end;
 TudpHeaderVersion4 = object(TipHeaderVersion4)
  SomeFields3 : packed array[0..7] of byte;
 end;
 TtcpHeaderVersion4 = object(TipHeaderVersion4)
  SomeFields4 : packed array[0..19] of byte;
 end;
 Tframe = object
  SomeFields5 : packed array[0..66000] of byte;
 end;
procedure Main;
var
 frame : Tframe;
begin
 frame.SomeFields5[14] := 234;
// TethernetHeader(frame). // typecast not possible.
// with frame as TethernetHeader do // operator not applicable
// begin
//  SomeFields5[4] := 123;
// end;
 // maybe pointers can help
 writeln( PipHeaderVersion4(@Frame).SomeFields2[0] );
end;
begin
  try
 Main;
  except
 on E:Exception do
   Writeln(E.Classname, ': ', E.Message);
  end;
  readln;
end.

Bye,
Skybuck.

Reply by email

Tiziano De Togni
to Florian Klaempfl: Indeed, especially if you want to win an obfuscation contest.

Florian Klaempfl ha scritto:

Show quoted text 6 lines
Skybuck Flying schrieb: > One drawback of objects already discovered: > > Objects cannot have the same field identifiers. Indeed, especially if you want to win an obfuscation contest.

ok, this is true for object type, but it should not be extended to class types. Look at this example taken from Delphi Help:

type
   TAncestor = class
     Value: Integer;
   end;
   TDescendant = class(TAncestor)
     Value: string;  // hides the inherited Value field
   end;
var
   MyObject: TAncestor;
begin
   MyObject := TDescendant.Create;
   // MyObject.Value := 'Hello!';  // error
   TDescendant(MyObject).Value := 'Hello!';  // works!
end;

it compiles correctly in Delphi (5 and 7) but FPC (v2.2.0 - compiled with Params Values=" -S2cdgi -OG1 -gl -WG -vewnhi") still says that there is a duplicate identifier "Value"...

am I correct?

tiziano ______________________________________ http://digilander.libero.it/tizzziano/

Reply by email

Vincent Snijders
to Tiziano De Togni
Tiziano De Togni wrote 35 lines
Florian Klaempfl ha scritto: > Skybuck Flying schrieb: >> One drawback of objects already discovered: >> >> Objects cannot have the same field identifiers. > > Indeed, especially if you want to win an obfuscation contest. ok, this is true for object type, but it should not be extended to class types. Look at this example taken from Delphi Help: type TAncestor = class Value: Integer; end; TDescendant = class(TAncestor) Value: string; // hides the inherited Value field end; var MyObject: TAncestor; begin MyObject := TDescendant.Create; // MyObject.Value := 'Hello!'; // error TDescendant(MyObject).Value := 'Hello!'; // works! end; it compiles correctly in Delphi (5 and 7) but FPC (v2.2.0 - compiled with Params Values=" -S2cdgi -OG1 -gl -WG -vewnhi") still says that there is a duplicate identifier "Value"... am I correct?

This is not allowed in {$mode objfpc}, because of the reasons Florian memtioned. It is allowed in {$mode delphi}.

Vincent

Reply by email

Tiziano De Togni
to Vincent Snijders: This is not allowed in {$mode objfpc}, because of the reasons Florian memtioned. It is…

Vincent Snijders ha scritto:

Show quoted text 12 lines
Tiziano De Togni schreef: > Florian Klaempfl ha scritto: >> Skybuck Flying schrieb: >>> One drawback of objects already discovered: > > am I correct? > This is not allowed in {$mode objfpc}, because of the reasons Florian memtioned. It is allowed in {$mode delphi}. Vincent

errr... I tryied various combinations of options before posting, but did not try {$mode Delphi}... :-(

going back to read the manuals...

to Bee: Not so sure now, compilation depends on a lot of details...

tiziano ______________________________________ http://digilander.libero.it/tizzziano/

Reply by email

Jonas Maebe
to Tiziano De Togni
Tiziano De Togni wrote 14 lines
Vincent Snijders ha scritto: > Tiziano De Togni schreef: >> Florian Klaempfl ha scritto: >>> Skybuck Flying schrieb: >>>> One drawback of objects already discovered: >> >> am I correct? >> > This is not allowed in {$mode objfpc}, because of the reasons > Florian memtioned. It is allowed in {$mode delphi}. > Vincent errr... I tryied various combinations of options before posting, but did not try {$mode Delphi}... :-(

-S2 is the same as {$mode objfpc} and -Sd is the same as {$mode delphi}. With -S2cdgi you are trying to set both {$mode objfpc} (-S2) and {$mode delphi} (-Sd). There is a bug in the compiler though, because for some reason -S2d does not seem to properly set Delphi mode (or unset objfpc mode) while it should.

Jonas

Reply by email

Skybuck Flying
to Florian Klaempfl

In every language I know, words can have multiple meanings.

The context in which the words are used determines their meaning.

One possible reason could be because there is so much to describe that coming up with unique words might be impossible or inpractical.

Bye,
Skybuck.

Show quoted text 16 lines
Skybuck Flying schrieb: > For records, I would use an extension field like: > > IP.Payload > > and > > UDP.Payload > > I would hardly call that obfuscation :) Having the same name for different things is always obfuscation. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Marco van de Voort
to Skybuck Flying
In every language I know, words can have multiple meanings.

Natural languages yes. But they need a billion neurons that is trained for 20 years to interpret, not a simple automaton.

IOW, lots of computer languages don't.

One possible reason could be because there is so much to describe that coming up with unique words might be impossible or inpractical.

I think the main reason is that brains naturally don't process information _without_ context. It's not just words, but also intonation, facial expression of the speaker, posture etc.

Abstracting is a learned skill.

Reply by email

Skybuck Flying
to Daniël Mantione: Op Fri, 15 Feb 2008, schreef Skybuck Flying: Empty records are valid Pascal. Nothing in…

There is another great limitation of your suggested solution.

The offsets for the objects are bound at compile time.

While the record solution allows the offsets to be determined at run time.

Making the record solution a more flexible solution.

In other words objects need to specify their ancestor at compile time creating the inflexibility.

The make things even worse. For every possibility a new object declaration would be needed and finally it would be an unacceptable solution because this would probably add runtime type information to the objects thereby adding unwanted fields.

However there might be a different solution which might still be interesting:

1. Non-inherited objects.

2. Maybe empty objects ?

I shall investigate those later on.

Bye,
Skybuck.

Earlier message 50 lines
----- Original Message ----- From: "Daniël Mantione" To: "FPC-Pascal users discussions" Sent: Saturday, February 16, 2008 5:24 PM Subject: Re: [fpc-pascal] Empty record inside another record ? Op Fri, 15 Feb 2008, schreef Skybuck Flying: > To me it seems like some kind of trick, to extend a record at runtime. > > The empty record field, functions as a sort of offset/label/pointer if you > will to the new fields that will will be extended to the record by simply > allocating more memory then the size of the record. > > Then this "label"/"field" can be used as a sort of offset, by typecasting > it > to some extension record type. > > Could be pretty handy, quite impressive trick. > > However, is it safe to use ? Empty records are valid Pascal. > I cannot find anything in the documentation about this ? Nothing in the documentation says it is forbidden either. The reason it is not explicetely mentioned is because there exists a much better method, objects: type base_structure=object field1:byte; end; extended_structure=object(base_structure) field2:byte; end; Daniël -------------------------------------------------------------------------------- > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Skybuck Flying
to Daniël Mantione: Op Fri, 15 Feb 2008, schreef Skybuck Flying: Empty records are valid Pascal. Nothing in…

Finally there is another question remaining:

Are objects always packed ?

If not then it could be a problem.

Something which records do allow.

Bye,
Skybuck.

Earlier message 50 lines
----- Original Message ----- From: "Daniël Mantione" To: "FPC-Pascal users discussions" Sent: Saturday, February 16, 2008 5:24 PM Subject: Re: [fpc-pascal] Empty record inside another record ? Op Fri, 15 Feb 2008, schreef Skybuck Flying: > To me it seems like some kind of trick, to extend a record at runtime. > > The empty record field, functions as a sort of offset/label/pointer if you > will to the new fields that will will be extended to the record by simply > allocating more memory then the size of the record. > > Then this "label"/"field" can be used as a sort of offset, by typecasting > it > to some extension record type. > > Could be pretty handy, quite impressive trick. > > However, is it safe to use ? Empty records are valid Pascal. > I cannot find anything in the documentation about this ? Nothing in the documentation says it is forbidden either. The reason it is not explicetely mentioned is because there exists a much better method, objects: type base_structure=object field1:byte; end; extended_structure=object(base_structure) field2:byte; end; Daniël -------------------------------------------------------------------------------- > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Daniël Mantione
to Skybuck Flying

Op Sun, 24 Feb 2008, schreef Skybuck Flying:

Finally there is another question remaining: Are objects always packed ?

No, to get packed objects you have to declare them packed. A record and object with the same field list have the same binary layout.

Daniël

Reply by email

Skybuck Flying
to Daniël Mantione: Op Fri, 15 Feb 2008, schreef Skybuck Flying: Empty records are valid Pascal. Nothing in…

There is another major drawback to your supposedly better method:

Object inheritance forces all fields to be accessable from the root:

SomeRoot.SomeField := ...;

While nesting has nice grouping:

SomeRoot.SomeHeader.SomeOtherHeader.SomeField := 5;

Bye,
Skybuck.

Earlier message 50 lines
----- Original Message ----- From: "Daniël Mantione" To: "FPC-Pascal users discussions" Sent: Saturday, February 16, 2008 5:24 PM Subject: Re: [fpc-pascal] Empty record inside another record ? Op Fri, 15 Feb 2008, schreef Skybuck Flying: > To me it seems like some kind of trick, to extend a record at runtime. > > The empty record field, functions as a sort of offset/label/pointer if you > will to the new fields that will will be extended to the record by simply > allocating more memory then the size of the record. > > Then this "label"/"field" can be used as a sort of offset, by typecasting > it > to some extension record type. > > Could be pretty handy, quite impressive trick. > > However, is it safe to use ? Empty records are valid Pascal. > I cannot find anything in the documentation about this ? Nothing in the documentation says it is forbidden either. The reason it is not explicetely mentioned is because there exists a much better method, objects: type base_structure=object field1:byte; end; extended_structure=object(base_structure) field2:byte; end; Daniël -------------------------------------------------------------------------------- > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Daniël Mantione
to Skybuck Flying

Op Fri, 29 Feb 2008, schreef Skybuck Flying:

Show quoted text 9 lines
There is another major drawback to your supposedly better method: Object inheritance forces all fields to be accessable from the root: SomeRoot.SomeField := ...; While nesting has nice grouping: SomeRoot.SomeHeader.SomeOtherHeader.SomeField := 5;

I'd say it is a metter of taste. Anyway, you are free to use any method you like as both are valid code. End of discussion.

Daniël

Reply by email