Sign in Join

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

Mailing lists / fpc-devel / 2001-03

Incorrect warning msg using 'not' and 'DWord' (FPC 1.0.4)

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Marcel van der Heide

Compiling the following prog with warnings enabled and range checking on gives (incorrectly) 2 warning msgs about mixing signed expressions and cardinals.
When using 'or' instead of 'and not' it compiles without warnings. When using Word instead of DWord, no warnings either.

Best wishes,

Marcel

platfrom: linux
version: fpc 1.0.4

program test;
const
  cTest1 =        $03;
  cTest2: DWord = $03;
var
  vTest: DWord;
begin
  vTest:= vTest and not cTest1;
  vTest:= vTest and not cTest2;
end.

Reply by email

Jonas
Marcel van der Heide wrote 16 lines
> platfrom: linux version: fpc 1.0.4 program test; const cTest1 = $03; cTest2: DWord = $03; var vTest: DWord; begin vTest:= vTest and not cTest1; vTest:= vTest and not cTest2; end.

The second now doesn't give a warning anymore, but the first still does. The reason is that if you don't explicitely typecast a constant in FPC, it's always a longint (in 1.0.x at least).

Jonas

Reply by email

Marcel van der Heide
to Jonas
you wrote 5 lines
The second now doesn't give a warning anymore, but the first still does. The reason is that if you don't explicitely typecast a constant in FPC, it's always a longint (in 1.0.x at least). Jonas

Thanks a lot.
I was wondering if constants are always longints. You've answered that now too.
There remains one problem. If I specify the type of a constant like this: const

  cTest1: DWord = $03;

it becomes a typed constant, and is treated like a initialized variable, so one can not use it in a case like the following construction anymore. case x of
cTest1: ...
...
end

Thanks again, and best wishes,

Marcel

Reply by email

Jonas
Marcel van der Heide wrote 12 lines
Thanks a lot. I was wondering if constants are always longints. You've answered that now too. There remains one problem. If I specify the type of a constant like this: const cTest1: DWord = $03; it becomes a typed constant, and is treated like a initialized variable, so one can not use it in a case like the following construction anymore. case x of cTest1: ... ... end

You can use

Const
  cTest1 = DWord($03);

However, I think support for this was only introduced after 1.0.4. It is accepted in previous versions, but the type cast is ignored. I found out that for some reason even in the current version it still gives a warning when using this, but I'm debugging that right now.

Jonas

Reply by email

Jonas
Jonas wrote 8 lines
You can use Const cTest1 = DWord($03); However, I think support for this was only introduced after 1.0.4. It is accepted in previous versions, but the type cast is ignored. I found out that for some reason even in the current version it still gives a warning when using this, but I'm debugging that right now.

I only implemented that functionality in 1.1 it seems. I've now added it to 1.0.5 as well, and now there are no warnings anymore there.

It doesn't compile under 1.1 though (when using -Cr). The reason is that in 1.0.x, currently the result of not(constant) is always a longint (= sizeof(constant_expressions)), except when the argument is a cardinal (then the result is also a cardinal).

In 1.1 however, the resulttype of not(constant) = resulttype of the constant itself. Also, constants held in int64's there, instead of in longints. This means you get

not(cardinal(3)) = $ffff ffff ffff fffc

which then is implicitely converted to a cardinal (since the resulttype of not is defined as being the same as that of the argument) and as such gives a range check error. We can fix this similarly as in 1.0.x by changing the resulttype of not(constant) to int64 (except when the argument is a qword, then the result will also be a qword), but I don't know if that is a satisfactory solution.

Jonas

Reply by email