### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

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

#### winni

• Hero Member
• Posts: 2418
##### Re: How to force the not operator to return a byte
« Reply #30 on: May 15, 2021, 11:35:21 pm »
RTFM!

Siezof returns the size of variables. Simple as well as records.

And if do a sizeof(SomePointer) it return the size of the pointer.

That's why it is called sizeof.

Winni

#### engkin

• Hero Member
• Posts: 2819
##### Re: How to force the not operator to return a byte
« Reply #31 on: May 15, 2021, 11:55:57 pm »
Great information, Winni!!

Are you suggesting a bug in SizeOf or its documentation?

#### y.ivanov

• Full Member
• Posts: 132
##### Re: How to force the not operator to return a byte
« Reply #32 on: May 16, 2021, 12:32:28 am »
*snip*

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.

I see. But you wrote:
Code: Pascal  [Select][+][-]
1. SizeOf(NOT SomeValue) equals SizeOf(PtrInt)

It's a sloppy writing.

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.

Actually, no. May be you're hopeful that I can differentiate between (128 or 64) and \$FF but I can't. Both:
Code: [Select]
`not (128 or 64)` and
Code: [Select]
`\$FF xor (128 or 64)` are non-terminal <expr> on terminals \$FF, 128, 64 (all fit in a byte, i.e. 0..2^8-1) and I can't see the reason the former will be widened to PtrInt and the latter -not.
Nowhere I can see a type hint to the compiler as it would be if they're declared as variables (e.g. V: Type).
Why the widening rules for not and xor would differ?

#### winni

• Hero Member
• Posts: 2418
##### Re: How to force the not operator to return a byte
« Reply #33 on: May 16, 2021, 12:34:01 am »
Hi !

I have read the sizeof documentation of UCSD Pascal 40 yers ago.Since then has not much changed.

Winni

#### winni

• Hero Member
• Posts: 2418
##### Re: How to force the not operator to return a byte
« Reply #34 on: May 16, 2021, 01:02:04 am »
Hi!

Perhaps one usefull tip:

If you use NOT without any type casting, the result is in the native size of your machine:

On 32Bit machines it is 4 bytes
On 64Bit machines it is 8 bytes

It does not matter if the input is a byte, a word or an integer.

Winni

#### engkin

• Hero Member
• Posts: 2819
##### Re: How to force the not operator to return a byte
« Reply #35 on: May 16, 2021, 01:10:58 am »
*snip*

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.

I see.

I thought that meant we are done!!

But you wrote:
Code: Pascal  [Select][+][-]
1. SizeOf(NOT SomeValue) equals SizeOf(PtrInt)

It's a sloppy writing.

Why do think it is sloppy? How do you prefer I write it?

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.

Actually, no. May be you're hopeful that I can differentiate between (128 or 64) and \$FF but I can't. Both:
Code: [Select]
`not (128 or 64)` and
Code: [Select]
`\$FF xor (128 or 64)` are non-terminal <expr> on terminals \$FF, 128, 64 (all fit in a byte, i.e. 0..2^8-1) and I can't see the reason the former will be widened to PtrInt and the latter -not.
Nowhere I can see a type hint to the compiler as it would be if they're declared as variables (e.g. V: Type).
Why the widening rules for not and xor would differ?

I don't have a Delphi. Do you have [access to] a recent version of Delphi?
If Delphi widens the result of NOT, FPC is going to follow for compatibility. Otherwise it is a bug.

#### engkin

• Hero Member
• Posts: 2819
##### Re: How to force the not operator to return a byte
« Reply #36 on: May 16, 2021, 01:13:06 am »
Hi!

Perhaps one usefull tip:

If you use NOT without any type casting, the result is in the native size of your machine:

On 32Bit machines it is 4 bytes
On 64Bit machines it is 8 bytes

It does not matter if the input is a byte, a word or an integer.

Winni

Yes, Winni, that is correct. Is it documented? How about Delphi?

#### y.ivanov

• Full Member
• Posts: 132
##### Re: How to force the not operator to return a byte
« Reply #37 on: May 16, 2021, 01:20:40 am »
Hi !

I have read the sizeof documentation of UCSD Pascal 40 yers ago.Since then has not much changed.

Winni
+1 for mentioning UCSD Pascal.

I doubt it has SizeOf, it is a C/C++ operator and should return the actual storage size of a variable or a type. As long it is used over a constant, which should be substituted as a literal, (@engkin) it can be considered as a bug.

IMHO,
Quote
If Delphi widens the result of NOT, FPC is going to follow for compatibility. Otherwise it is a bug.
is not an excuse.

#### engkin

• Hero Member
• Posts: 2819
##### Re: How to force the not operator to return a byte
« Reply #38 on: May 16, 2021, 01:31:29 am »
(@engkin) it can be considered as a bug.

The OP made it clear that it changed after FPC 3.0.4.
Mark PMed PascalDragon, but we did not see his response.
Without comparing it with Delphi I cannot be sure if it is a bug or a feature.
Since you are that sure, maybe you can file a bug report.
« Last Edit: May 16, 2021, 01:35:35 am by engkin »

#### winni

• Hero Member
• Posts: 2418
##### Re: How to force the not operator to return a byte
« Reply #39 on: May 16, 2021, 01:33:28 am »
Hi!

As I said:

If you repair a Delphi bug in Lazarus, it is considered to be a bug, because it is not Delphi compatible.

That's the way to bring people in the madhouse.

Winni

#### y.ivanov

• Full Member
• Posts: 132
##### Re: How to force the not operator to return a byte
« Reply #40 on: May 16, 2021, 01:47:45 am »
*snip*
Since you are that sure, maybe you can file a bug report.
I'd rather not use sizeof that way.
What bothers me more is the different interpretations of the otherwise identical bitwise not and xor

#### engkin

• Hero Member
• Posts: 2819
##### Re: How to force the not operator to return a byte
« Reply #41 on: May 16, 2021, 02:36:22 am »
*snip*
Since you are that sure, maybe you can file a bug report.
I'd rather not use sizeof that way.
What bothers me more is the different interpretations of the otherwise identical bitwise not and xor

Just to be clear, when I mentioned the bug report I was talking about NOT.

#### BobDog

• Jr. Member
• Posts: 78
##### Re: How to force the not operator to return a byte
« Reply #42 on: May 16, 2021, 11:20:44 am »

Getting all tied up here, that's for sure.
Code: Pascal  [Select][+][-]
1.
2. {\$MACRO ON}
3.  {\$define c:= knot(a or b) }
4.
5.  const
6.  a=128;
7.  b=64;
8.
9.   function knot(i:integer):byte;
10.   begin
11.   exit(not i);
12.   end;
13.
14. begin
15. writeln(c);
16. writeln;
18. end.

#### tetrastes

• Full Member
• Posts: 117
##### Re: How to force the not operator to return a byte
« Reply #43 on: May 16, 2021, 12:28:03 pm »
What bothers me more is the different interpretations of the otherwise identical bitwise not and xor

It seems that you do not understand the difference between byte variables and ordinary constants. Then consider them as integers.
And maybe the output of this code will help you.
Code: Pascal  [Select][+][-]
1. const
2.   a = 128;
3.   b = 64;
4.   c = not (a or b);
5.   d = \$FF xor (a or b);
6.
7. var
8.   ba : byte = 128;
9.   bb : byte = 64;
10.   bc, bd : byte;
11.
12.   ia : integer = 128;
13.   ib : integer = 64;
14.   ic, id : integer;
15.
16. begin
17.   writeln('constants');
18.   writeln(c);
19.   writeln(d);
20.   writeln;
21.
22.   bc := not (ba or bb);
23.   bd := \$FF xor (ba or bb);
24.   writeln('bytes');
25.   writeln(bc);
26.   writeln(bd);
27.   writeln;
28.
29.   writeln('integers');
30.   ic := not (ia or ib);
31.   id := \$FF xor (ia or ib);
32.   writeln(ic);
33.   writeln(id);
35. end.

#### molly

• Hero Member
• Posts: 2330
##### Re: How to force the not operator to return a byte
« Reply #44 on: May 16, 2021, 12:51:05 pm »
Not(constant) does something different then is assumed xor does not suffer from this negation 'error'.

Code: Pascal  [Select][+][-]
1. program test;
2.
3. {\$MODE OBJFPC}
4.
5. (*
6. https://freepascal.org/docs-html/ref/refsu4.html#x26-250003.1.1
7.
8. With the exception of floating point value types, all base types
9. are ordinal types.
10.
11. A list of predefined integer types is presented in table (3.1).
12.
13. Remark: The compiler decides on the type of an integer constant
14. based on the value: An integer constant gets the smallest possible
15. signed type. The first match in table (3.3) is used.
16.
17. That means constants in the range -128..127 are mapped to shortint,
18. constants in range 128..255 are mapped to byte, etc.
19. Constants in the range 2147483647..high(cardinal) are parsed as
20. cardinals, and all decimal constants which do not fit either of
21. the above ranges are parsed as 64-bit integer constants.
22.
23. As a pascal compiler, Free Pascal does automatic type conversion and
24. upgrading in expressions where different kinds of integer types are
25. used:
26. 1 Every platform has a “native” integer size, depending on whether
27.   the platform is 8-bit, 16-bit, 32-bit or 64-bit. E. g. on AVR this
28.   is 8-bit.
29. 2 Every integer smaller than the “native” size is promoted to a
30.   signed version of the “native” size. Integers equal to the “native”
31.   size keep their signedness.
32. 3 The result of binary arithmetic operators (+, -, *, etc.) is
33.   determined in the following way:
34.   a If at least one of the operands is larger than the native integer
35.     size, the result is chosen to be the smallest type that encompasses
36.     the ranges of the types of both operands. This means that mixing an
37.     unsigned with a smaller or equal in size signed will produce a
38.     signed type that is larger than both of them.
39.   b If both operands have the same signedness, the result is the same
40.     type as them. The only exception is subtracting (-): in the case of
41.     unsigned - unsigned subtracting produces a signed result in FPC
42.     (as in Delphi, but not in TP7).
43.   c Mixing signed and unsigned operands of the “native” int size
44.     produces a larger signed result. This means that mixing longint and
45.     longword on 32-bit platforms will produce an int64. Similarly,
46.     mixing byte and shortint on 8-bit platforms (AVR) will produce
47.     a smallint.
48. *)
49.
50. begin
51.   WriteLn(64);
52.   WriteLn(SizeOf(64));
53.   WriteLn(128);
54.   WriteLn(SizeOf(128));
55.   WriteLn(128 or 64);
56.   WriteLn(SizeOf(128 or 64));
57.   WriteLn(not(128 or 64));
58.   WriteLn(SizeOf(not(128 or 64)));
59. end.
60.
61. (*
62.   64
63.   1
64.   128
65.   1
66.   192
67.   1
68.   -193
69.   8
70. *)
71.
72.

It's written in the documentation. It requires to read those line that apply for this situation