Sign in Join

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

Mailing lists / fpc-pascal / 2006-09

macros with parameters

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Marc Santhoff

Hi,

the docs only show examples of macros without any parameters. Is it possible to use them?

Can I make this work anyhow:

{$MACRO ON}
{$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)}
type
	s1_t = record
		a: longint;
		b: single;
		c: double;
	end;
var
	s1: s1_t;
BEGIN
	s1.a := 12345;
	s1.b := 1.000000001;
	s1.c := 1.000000002;
	writeln(HOFFSET(s1, a)); { Line 32 in my code }
END.

Written as it is the compiler doesn't like it:

$ fpc offsetof
Free Pascal Compiler version 2.0.2 [2005/11/17] for i386
Copyright (c) 1993-2005 by Florian Klaempfl
Target OS: FreeBSD/ELF for i386
Compiling offsetof.pas
offsetof.pas(32,10) Error: Identifier not found "HOFFSET"
offsetof.pas(32,22) Error: Identifier not found "a"
offsetof.pas(32,25) Error: Illegal expression

Other solutions are very welcome...

TIA,
Marc

Reply by email

Michalis Kamburelis
to Marc Santhoff
Marc Santhoff wrote 39 lines
Hi, the docs only show examples of macros without any parameters. Is it possible to use them? Can I make this work anyhow: {$MACRO ON} {$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)} type s1_t = record a: longint; b: single; c: double; end; var s1: s1_t; BEGIN s1.a := 12345; s1.b := 1.000000001; s1.c := 1.000000002; writeln(HOFFSET(s1, a)); { Line 32 in my code } END. Written as it is the compiler doesn't like it: $ fpc offsetof Free Pascal Compiler version 2.0.2 [2005/11/17] for i386 Copyright (c) 1993-2005 by Florian Klaempfl Target OS: FreeBSD/ELF for i386 Compiling offsetof.pas offsetof.pas(32,10) Error: Identifier not found "HOFFSET" offsetof.pas(32,22) Error: Identifier not found "a" offsetof.pas(32,25) Error: Illegal expression Other solutions are very welcome...

Macros with parameters are not supported, AFAIK. I always workaround it by employing the fact that macros within macros are expanded. So instead of

  {$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)}

you can define parameter-less macro like

  {$define HOFFSET := pointer(@HOFFSET_rec.HOFFSET_field) -
pointer(@HOFFSET_rec)}

(I prefix macro params with "HOFFSET_" just for safety, you could as well just use original "rec" and "field" identifiers). And then to use it, instead of

  writeln(HOFFSET(s1, a));

you can write

  {$define HOFFSET_rec := s1}
  {$define HOFFSET_field := a}
  writeln(HOFFSET);

This way you get behavior of macros with parameters. Admittedly, this looks clumsy, but at least works.

Michalis

Reply by email

Marc Santhoff
to Michalis Kamburelis
Michalis Kamburelis wrote 42 lines
Marc Santhoff wrote: > Hi, > > the docs only show examples of macros without any parameters. Is it > possible to use them? > > Can I make this work anyhow: > > {$MACRO ON} > {$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)} > > type > s1_t = record > a: longint; > b: single; > c: double; > end; > var > s1: s1_t; > BEGIN > s1.a := 12345; > s1.b := 1.000000001; > s1.c := 1.000000002; > > writeln(HOFFSET(s1, a)); { Line 32 in my code } > END. > > Written as it is the compiler doesn't like it: > > $ fpc offsetof > Free Pascal Compiler version 2.0.2 [2005/11/17] for i386 > Copyright (c) 1993-2005 by Florian Klaempfl > Target OS: FreeBSD/ELF for i386 > Compiling offsetof.pas > offsetof.pas(32,10) Error: Identifier not found "HOFFSET" > offsetof.pas(32,22) Error: Identifier not found "a" > offsetof.pas(32,25) Error: Illegal expression > > Other solutions are very welcome... > Macros with parameters are not supported, AFAIK.

Heavy grep'ing found some files with single parameter macros, so in principle it may work.

Show quoted text 24 lines
I always workaround it by employing the fact that macros within macros are expanded. So instead of {$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)} you can define parameter-less macro like {$define HOFFSET := pointer(@HOFFSET_rec.HOFFSET_field) - pointer(@HOFFSET_rec)} (I prefix macro params with "HOFFSET_" just for safety, you could as well just use original "rec" and "field" identifiers). And then to use it, instead of writeln(HOFFSET(s1, a)); you can write {$define HOFFSET_rec := s1} {$define HOFFSET_field := a} writeln(HOFFSET); This way you get behavior of macros with parameters. Admittedly, this looks clumsy, but at least works.

This does not do what I need, the goal is to pass arbitrary record variables and contained field names for calculating the offset in byte of the field from the start of the record.

I've started trying by making it a function but found no way to declare the function parameters for passing any record type without casting.

I'll try thinking about recursive macros some more, maybe there is a soolution in that direction ...

Thanks a lot,
Marc

Reply by email