Recent

Author Topic: How to force the not operator to return a byte  (Read 13473 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: How to force the not operator to return a byte
« Reply #15 on: May 14, 2021, 11:18:31 pm »
I've PMed PascalDragon and asked him to drop in.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

tetrastes

  • Sr. Member
  • ****
  • Posts: 473
Re: How to force the not operator to return a byte
« Reply #16 on: May 15, 2021, 12:19:17 am »
As I understand it, you cannot use typed constants in expression in a constant declaration, because they in fact are some kind of variables (are placed in memory and initialized), while ordinary constants are analog of #define in C. This is quote from https://www.freepascal.org/docs-html/current/ref/refse9.html#x21-200002.1 :
Quote
When a previously declared ordinary constant is used in the code, the compiler will insert the actual value of the constant instead of the constant name.
Even this code
Code: Pascal  [Select][+][-]
  1. const
  2.   a : byte = 128;
  3.   c = a;
gives Illegal expression.
As for
Code: Pascal  [Select][+][-]
  1. const
  2.     a = byte(128);

this is still ordinary constant.
« Last Edit: May 15, 2021, 12:33:00 am by tetrastes »

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: How to force the not operator to return a byte
« Reply #17 on: May 15, 2021, 12:36:42 am »
As I understand it, you cannot use typed constants in expression in a constant declaration, because they in fact are some kind of variables (are placed in memory and initialized) ....

Hi!

Yes , you are right. We are still fighting with the idiotic Borland decision about typed constants from the last millenium.
And all that nonsense due to Delphi compatibility.

Winni

speter

  • Sr. Member
  • ****
  • Posts: 345
Re: How to force the not operator to return a byte
« Reply #18 on: May 15, 2021, 03:40:32 am »
interestingly, even the following gives a warning:
Code: Pascal  [Select][+][-]
  1. const
  2.   a = word(128);
  3.   b = word(64);
  4.   c = word(a or b);
  5.   d = byte(not c);   // Warning: range check error ... (-193)
  6.   e = word(not c);
  7.   f = byte(e);       // Warning: range check error ... (65343)
  8.   g = byte(lo(e));
  9.  
unit1.pas(56,8) Warning: range check error while evaluating constants (-193 must be between 0 and 255)
^^^^(56 = line 5 in the code above)
unit1.pas(58,7) Warning: range check error while evaluating constants (65343 must be between 0 and 255)
^^^^(58 = line 7 in the code above)

The code produces the following output (Win 10, 64bit)
Code: Text  [Select][+][-]
  1. a = 128
  2. b = 64
  3. c = 192
  4. d = 63
  5. e = 65343
  6. f = 63
  7. g = 63

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

speter

  • Sr. Member
  • ****
  • Posts: 345
Re: How to force the not operator to return a byte
« Reply #19 on: May 15, 2021, 03:59:49 am »
To answer the original question (in the subject line) :)
Code: Pascal  [Select][+][-]
  1. const
  2.   a = 128;
  3.   b = 64;
  4.   c = byte(lo(not (a or b)));

The code above gives the correct answer and has no warnings. :)

cheers
S.

PS: interestingly, the following code gives a compiler error:
Code: Pascal  [Select][+][-]
  1. const
  2.   a = 128;
  3.   b = 64;
  4.   c : byte = lo(not (a or b));
Error: range check error while evaluating constants (4294967103 must be between 0 and 255)
« Last Edit: May 15, 2021, 04:14:55 am by speter »
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to force the not operator to return a byte
« Reply #20 on: May 15, 2021, 06:10:20 am »
It is NOT a problem

SizeOf(NOT SomeValue) equals SizeOf(PtrInt)
that is 4 or 8 bytes

If the result is negative, it will NOT fit in any thing less than PtrInt. Or so the compiler thinks.

We have TWO solutions, NOT one:
1-Do NOT use NOT:
Code: Pascal  [Select][+][-]
  1. c=$FF xor (a or b);

OR

2-Do use NOT:
Code: Pascal  [Select][+][-]
  1. c=not (a or b) and $FF

1st Edit:
The first solution assumes both a and b are bytes.
The second solution does NOT care.

2nd Edit:
It's a feature If recent versions of Delphi.give similar warning?
« Last Edit: May 15, 2021, 06:34:05 am by engkin »

Roland57

  • Sr. Member
  • ****
  • Posts: 421
    • msegui.net
Re: How to force the not operator to return a byte
« Reply #21 on: May 15, 2021, 07:49:24 am »
Thank you all for the interesting discussion.

@speter

Sorry but, unless I am doing something wrong, your proposition doesn't seem to solve the problem: I still have a warning. (FPC 3.2.0, Linux 64.)

@engkin

Thank you. Both solutions work indeed.
My projects are on Gitlab and on Codeberg.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: How to force the not operator to return a byte
« Reply #22 on: May 15, 2021, 09:12:43 am »
As I understand it, you cannot use typed constants in expression in a constant declaration, because they in fact are some kind of variables (are placed in memory and initialized), while ordinary constants are analog of #define in C. This is quote from https://www.freepascal.org/docs-html/current/ref/refse9.html#x21-200002.1 :

Although I'd tried using the directive which should have disabled that.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

tetrastes

  • Sr. Member
  • ****
  • Posts: 473
Re: How to force the not operator to return a byte
« Reply #23 on: May 15, 2021, 09:51:42 am »
As I understand it, you cannot use typed constants in expression in a constant declaration, because they in fact are some kind of variables (are placed in memory and initialized), while ordinary constants are analog of #define in C. This is quote from https://www.freepascal.org/docs-html/current/ref/refse9.html#x21-200002.1 :

Although I'd tried using the directive which should have disabled that.

MarkMLl
This directive does not make them ordinary constants, it only tells compiler to place them in read-only memory (if architecture and system allow this).

tetrastes

  • Sr. Member
  • ****
  • Posts: 473
Re: How to force the not operator to return a byte
« Reply #24 on: May 15, 2021, 10:20:00 am »
PS: interestingly, the following code gives a compiler error:
Code: Pascal  [Select][+][-]
  1. const
  2.   a = 128;
  3.   b = 64;
  4.   c : byte = lo(not (a or b));
Error: range check error while evaluating constants (4294967103 must be between 0 and 255)

This code gives error when Range check (-Cr) option is on, otherwise it gives warning.

tetrastes

  • Sr. Member
  • ****
  • Posts: 473
Re: How to force the not operator to return a byte
« Reply #25 on: May 15, 2021, 10:30:31 am »
The first solution assumes both a and b are bytes.

If a and b are ordinary constants, they cannot be bytes. They do not reside in memory. They are evaluated to NUMBERS with some rules by compiler (for C we would say by preprocessor) before real compilation.
For ordinary constants we can speak only about range.
« Last Edit: May 15, 2021, 11:23:07 am by tetrastes »

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: How to force the not operator to return a byte
« Reply #26 on: May 15, 2021, 10:33:36 am »
In retrospect, I rather wish I'd not got involved in this :-)
Me too. This discussion practically scared the hell out of me

I'd hoped I can use fpc (my old beloved pascal) for low-level programming. Now I have my second thought about it.

I often use bitwise operations, e.g.
Code: [Select]
reg |= BITNO;
reg &= ~BITNO;
to set/clear a bit in a IO register which the C compiler usually translates the latter to a single assembly instruction.

Not sure it will work here.

Perhaps it is better to stick with the C-code for embedded purposes.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to force the not operator to return a byte
« Reply #27 on: May 15, 2021, 07:53:04 pm »
The first solution assumes both a and b are bytes.

If a and b are ordinary constants, they cannot be bytes. They do not reside in memory. They are evaluated to NUMBERS with some rules by compiler (for C we would say by preprocessor) before real compilation.
For ordinary constants we can speak only about range.

Yes, thank you. That's exactly what I meant. a and b should be within the range of what fits in a byte: 0..255 because "$FF xor" was used as a replacement for binary NOT. I should have made this clear but somehow I assumed it was obvious.

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: How to force the not operator to return a byte
« Reply #28 on: May 15, 2021, 10:19:19 pm »
SizeOf(NOT SomeValue) equals SizeOf(PtrInt)
that is 4 or 8 bytes

Not correct! Tested with FPC 3.2
Code: Pascal  [Select][+][-]
  1. var
  2.   B: Byte;
  3.   I: Integer;
  4. begin
  5.   I := SizeOf(not B); // = 1!

And why
Code: Pascal  [Select][+][-]
  1. $FF xor B
should be treated differently than
Code: Pascal  [Select][+][-]
  1. not B
?
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to force the not operator to return a byte
« Reply #29 on: May 15, 2021, 11:20:40 pm »
SizeOf(NOT SomeValue) equals SizeOf(PtrInt)
that is 4 or 8 bytes

Not correct! Tested with FPC 3.2
Code: Pascal  [Select][+][-]
  1. var
  2.   B: Byte;
  3.   I: Integer;
  4. begin
  5.   I := SizeOf(not B); // = 1!

How about you do the correct test!
Code: Pascal  [Select][+][-]
  1. const
  2.   b=1;
  3.  
  4. begin
  5.   WriteLn(SizeOf(b));
  6.   WriteLn(SizeOf(NOT b));
  7. //OR
  8.   WriteLn(SizeOf(1));
  9.   WriteLn(SizeOf(NOT 1));

Constants, remember? Ordinal constants.

And why
Code: Pascal  [Select][+][-]
  1. $FF xor B
should be treated differently than
Code: Pascal  [Select][+][-]
  1. not B
?

Hopefully you see the reason now.

 

TinyPortal © 2005-2018