Lazarus

Free Pascal => General => Topic started by: furious programming on May 08, 2021, 02:18:06 am

Title: [SOLVED] $STOP directive with value taken from SizeOf
Post by: furious programming on May 08, 2021, 02:18:06 am
There are several data types in my project, the size of which must be strictly defined. If the size of a given type is different than the required size, compilation is to be aborted and an appropriate message displayed in the Messages window. Currently, I do it this way:

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyType = OtherUnit.OtherType;
  3.  
  4.   {$IF SIZEOF(TMyType) <> 1}
  5.     {$STOP the size of the TMyType is not 1 byte}
  6.   {$ENDIF}

And it works great — in the event of a problem, compilation is interrupted and the fixed message is displayed in the message window.

However, this allows me to know that the size of a given data type is incorrect, but I don't know what it is. Is there any way to use SIZEOF and use the received value to format the message body? I mean something like this:

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyType = OtherUnit.OtherType;
  3.  
  4.   {$IF SIZEOF(TMyType) <> 1}
  5.     {$STOP the size of the TMyType is SIZEOF(TMyType) byte(s), but must be 1 byte}
  6.   {$ENDIF}

to receive this message:

Code: Pascal  [Select][+][-]
  1. 'the size of the TMyType is 4 byte(s), but must be 1 byte'

Is such a thing possible?
Title: Re: $STOP directive with value taken from SizeOf
Post by: speter on May 08, 2021, 02:32:32 am
Could you move the size check to the unit's initialisation section?

Something like (untested code):
Code: Pascal  [Select][+][-]
  1. unit xxx;
  2. interface
  3. uses ...
  4. type
  5.   TMyType = ...
  6.  ...
  7. implementation
  8. var
  9.   zzz : integer;
  10.  ...
  11.  
  12. begin
  13.   zzz := sizeof(TMyType);
  14.   if zzz <> 1 then
  15.     showmessage('TMyType is '+zzz.tostring+' bytes');
  16. end.
  17.  

Of course, this won't happen during compilation, so probably isn't that useful. ;(

cheers
S.
Title: Re: $STOP directive with value taken from SizeOf
Post by: 440bx on May 08, 2021, 02:37:12 am
Unfortunately I don't have an answer for you but, I have a question instead.  Do you happen to have a link to a page that documents all the functions that can be called at compile time ?

I ask for two reasons, I didn't know that sizeof could  be used in compiler directives.  I eventually found a documentation page where it was stated that "sizeof" could be used in compile time expressions but, I was not able to find a list of compile time functions.

Maybe (big maybe), "length" is another function that can be used in compiler directives (I haven't tried it but, it would be very nice if it were available.)

A page that documents all the functions that can be used in compiler directive expressions would be very nice.  If you happen to know of one, please do share.

Title: Re: $STOP directive with value taken from SizeOf
Post by: furious programming on May 08, 2021, 02:46:03 am
@speter: nope, I would like to use compiler directives to abort compilation, not to abort the application startup. 8)


Unfortunately I don't have an answer for you but, I have a question instead.  Do you happen to have a link to a page that documents all the functions that can be called at compile time ?

@440bx: hmm… no. Unfortunately, (AFAIK) the issue of directives is not fully documented. For example, the + operator that can be used with DEFINED is not described, but can be used to sum results of the DEFINED and then, test the result against the fixed number. Example:

Code: Pascal  [Select][+][-]
  1. {$IF DEFINED(FOO) + DEFINED(BAR) + DEFINED(QUX) <> 3}
  2.   {$STOP not all mandatory symbols declared}
  3. {$ENDIF}

Quote
I ask for two reasons, I didn't know that sizeof could  be used in compiler directives.

SIZEOF can be used in combination with $IF, but I don't know if it can be used to format the error message text. That's why I'm asking, if it is possible to somehow format the message text with some integers.
Title: Re: $STOP directive with value taken from SizeOf
Post by: 440bx on May 08, 2021, 02:56:04 am
@furious programming

Thank you for sharing what you know about it.
Title: Re: $STOP directive with value taken from SizeOf
Post by: PascalDragon on May 08, 2021, 03:49:38 pm
A page that documents all the functions that can be used in compiler directive expressions would be very nice.  If you happen to know of one, please do share.

How about this (https://www.freepascal.org/docs-html/current/prog/progsu127.html#x140-1410002.4.1) one? ;) (Though the arithmetic operators aren't documented (essentially the whole set is supported), so for those a bug report should be filed)
Title: Re: $STOP directive with value taken from SizeOf
Post by: furious programming on May 08, 2021, 06:41:12 pm
@PascalDragon: useful link, thanks. But can you answer my question? Is it possible to format the content of the error message?
Title: Re: $STOP directive with value taken from SizeOf
Post by: MarkMLl on May 08, 2021, 06:48:40 pm
@PascalDragon: useful link, thanks. But can you answer my question? Is it possible to format the content of the error message?

I don't think that will do what you want. I'm similarly paranoid about such things, but put them into assertions in the startup code where one /can/ get (and display) an unambiguous actual size.

Otherwise I suggest writing a cut-down test program which is compiled and run as part of the build sequence, i.e. very much like the traditional ./configure scripts would do on a unix platform.

MarkMLl
Title: Re: $STOP directive with value taken from SizeOf
Post by: Remy Lebeau on May 08, 2021, 09:43:55 pm
Is there any way to use SIZEOF and use the received value to format the message body?

No, because {$STOP} does not allow formatted messages.  You would have to check each size individually and {$STOP} a different message for each one, eg:

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyType = OtherUnit.OtherType;
  3.  
  4.   {$IF SIZEOF(TMyType) <> 1}
  5.     {$IF SIZEOF(TMyType) = 2}
  6.       {$STOP the size of the TMyType is 2 bytes, but must be 1 byte}
  7.     {$ELSEIF SIZEOF(TMyType) = 4}
  8.       {$STOP the size of the TMyType is 4 bytes, but must be 1 byte}
  9.     ...
  10.     {$ELSE}
  11.       {$STOP the size of the TMyType is > 1 byte, but must be 1 byte}
  12.     {$ENDIF}
  13.   {$ENDIF}

Needless to say, that is very verbose coding.  Probably not worth the effort.
Title: Re: $STOP directive with value taken from SizeOf
Post by: 440bx on May 08, 2021, 10:12:05 pm
How about this (https://www.freepascal.org/docs-html/current/prog/progsu127.html#x140-1410002.4.1) one? ;) (Though the arithmetic operators aren't documented (essentially the whole set is supported), so for those a bug report should be filed)
That is really nice, thank you.  I have to say, not an easy page to find. 

Also, I have not been able to find an "equivalent" in the FPC (pdf) documentation.

Thank you again, that is really useful.
Title: Re: $STOP directive with value taken from SizeOf
Post by: lucamar on May 09, 2021, 01:26:23 am
Also, I have not been able to find an "equivalent" in the FPC (pdf) documentation.

It's the Programmer's Guide, so prog.pdf. Chapter 2, section 2.4 for FPC 3.2.0
Title: Re: $STOP directive with value taken from SizeOf
Post by: 440bx on May 09, 2021, 01:43:21 am
It's the Programmer's Guide, so prog.pdf. Chapter 2, section 2.4 for FPC 3.2.0
You're right!. It's right there.  Thank you for pointing that out. 

I've read all the manuals from top to bottom but, obviously not all the information got recorded in my neurons.  I gotta upgrade my memory to DDR4.
Title: Re: $STOP directive with value taken from SizeOf
Post by: lucamar on May 09, 2021, 02:16:40 am
If it's any consolation, I had to unzip the pdf docs and look into it because I didn't remember whether it was really there despite having just read that manual (again!) :-[
Title: Re: $STOP directive with value taken from SizeOf
Post by: trev on May 09, 2021, 02:28:21 am
How about this (https://www.freepascal.org/docs-html/current/prog/progsu127.html#x140-1410002.4.1) one? ;) (Though the arithmetic operators aren't documented (essentially the whole set is supported), so for those a bug report should be filed)

Bug report filed: https://bugs.freepascal.org/view.php?id=38866  O:-)
Title: Re: $STOP directive with value taken from SizeOf
Post by: PascalDragon on May 09, 2021, 06:05:27 pm
@PascalDragon: useful link, thanks. But can you answer my question? Is it possible to format the content of the error message?

No, it's not.

Also, I have not been able to find an "equivalent" in the FPC (pdf) documentation.

The preprocessor related parts are documented in the programmer's guide, cause it's strictly not part of the language.
Title: Re: $STOP directive with value taken from SizeOf
Post by: MarkMLl on May 09, 2021, 06:32:44 pm
The preprocessor related parts are documented in the programmer's guide, cause it's strictly not part of the language.

Does that mean that the compiler could invoke a different program as its front-end preprocessor? >:-)

MarkMLl
Title: Re: $STOP directive with value taken from SizeOf
Post by: PascalDragon on May 10, 2021, 01:29:07 pm
Does that mean that the compiler could invoke a different program as its front-end preprocessor? >:-)

Read what I wrote: I said that the preprocessor is not part of the language. It is however an intrinsic part of the compiler and not changeable.
Title: Re: $STOP directive with value taken from SizeOf
Post by: MarkMLl on May 10, 2021, 01:39:32 pm
Does that mean that the compiler could invoke a different program as its front-end preprocessor? >:-)

Read what I wrote: I said that the preprocessor is not part of the language. It is however an intrinsic part of the compiler and not changeable.

A simple "NO." would have sufficed. I very carefully said /could/, not /can/, so with respect read what *I* wrote.

Having said which, such a thing might be useful since it would allow a standard response to suggestions like "Please can we have braces as block markers": "Sure, write a suitable preprocessor.".

MarkMLl
Title: Re: $STOP directive with value taken from SizeOf
Post by: furious programming on May 11, 2021, 03:51:33 am
Ok, now I know everything I wanted. Thank you very much guys for answers.
Title: Re: $STOP directive with value taken from SizeOf
Post by: PascalDragon on May 11, 2021, 08:28:57 am
Having said which, such a thing might be useful since it would allow a standard response to suggestions like "Please can we have braces as block markers": "Sure, write a suitable preprocessor.".

No. (You asked for it :P )
Title: Re: $STOP directive with value taken from SizeOf
Post by: MarkMLl on May 11, 2021, 09:06:55 am
Having said which, such a thing might be useful since it would allow a standard response to suggestions like "Please can we have braces as block markers": "Sure, write a suitable preprocessor.".

No. (You asked for it :P )

GRIN

MarkMLl
TinyPortal © 2005-2018