INC(CARDINAL,INTEGER) problem 
Author Message
 INC(CARDINAL,INTEGER) problem

Hi!
I have a small problem with the INC standard procedure. As
you can see below, my compilers (two different Amiga M2 compilers)
report an error in line L1, but they have no problem with line L2.
But when I start the compiled program (L1 removed before), then
the runtimesystem will report an overflow.
Now someone else tested this small module on a pc and an apple
(I do not know the compilers, sorry) and told me, that they
make nearly the same mistakes as my compilers.
What is wrong? Should a compiler report an error (like he does
correctly in L1) or should it handle the addition correctly
(C=98, for the example below)?

Bye
   Stefan Tiemann (still misusing the account of my brother :)

---------------------------------------------------------------
MODULE Inc;
VAR
   I: INTEGER;
   C: CARDINAL;
BEGIN
   I:= -1;
   C:= 99;
   C:= C + I;   (* L1: Compiler reports: incompatible operand type *)
   INC(C, I);   (* L2: Compiler compiles, RTS reports an overflow *)
END Inc.



Mon, 07 Dec 1998 03:00:00 GMT  
 INC(CARDINAL,INTEGER) problem

Quote:

>I have a small problem with the INC standard procedure. As
>you can see below, my compilers (two different Amiga M2 compilers)
>report an error in line L1, but they have no problem with line L2.

[..]

Quote:
>---------------------------------------------------------------
>MODULE Inc;
>VAR
>   I: INTEGER;
>   C: CARDINAL;
>BEGIN
>   I:= -1;
>   C:= 99;
>   C:= C + I;   (* L1: Compiler reports: incompatible operand type *)
>   INC(C, I);   (* L2: Compiler compiles, RTS reports an overflow *)
>END Inc.

The mixing of CARDINAL and INTEGER leads to some awkward
problems that language designers have never resolved
satisfactorily.  Wirth tried to solve the problem (in Oberon)
by removing CARDINAL from the language, but in my opinion
that was a step backward.  (In my own programmming, I've
found that CARDINAL is a very useful type to have, whereas
INTEGER is something that I need only rarely.)  The ISO
standardisation group tried at one time to solve the problem
by making CARDINAL a subrange of INTEGER, although in the
end that change didn't make it into the language.

Here's my analysis of what's going wrong:

Line L1: The question to ask here is what you really intend.
If this line is intended to have the effect of
"C := C + VAL(CARDINAL,I)" then it's clear that it shouldn't
work, because the value of I is out of range for a CARDINAL.
Conclusion: this line shouldn't be done as CARDINAL arithmetic,
therefore you have to use signed arithmetic.  There are
two ways to achieve this.  Either:
  (a) declare C as an INTEGER variable, or
  (b) specifically say that you want INTEGER arithmetic, by
      writing
          C := VAL(CARDINAL, VAL(INTEGER, C) + I)
      This is admittedly messy, but what do you expect?
      You have to have some way of telling the compiler
      whether you want it to work with INTEGER or CARDINAL
      arithmetic.

In any case, the language standard is quite clear on this
point: line L1 is illegal, because this sort of "mixed mode"
arithmetic is not allowed in Modula-2.  If it were allowed,
then the compiler would have to do some hidden type
conversions, and this is contrary to the spirit of a
strongly-typed language.

Line L2: This is a little more tricky.  I'd have to do some
careful searching through the language specification to see
whether it's legal, and for the moment I don't have the
patience to do that.  My guess, though, is that it's probably
illegal, and that your compiler was wrong in accepting it
without an error message.

Assuming, however, that it is legal, there are two possible
interpretations:
   Interpretation 1: the line means INC(C,VAL(CARDINAL,I)).
      Under this interpretation there should be a run-time
      error, because I is out of range.
   Interpretation 2: the line means INC(C,SYSTEM.CAST(CARDINAL,I)).
      Under this interpretation you're trying to increment
      C by MAX(CARDINAL), and of course the calculation overflows.

All of this is pretty obvious to experienced M2 programmers,
but to a beginner it probably raises the question "why is
this operation so difficult in M2, when it's so easy in
other languages?"  To answer this, you need to see what
happens in other languages.

Approach 1 (fortran, Oberon, various other languages): you
can decide not to support unsigned arithmetic, and then the
problem goes away.  But, to do this, you have to give up
using the very useful CARDINAL type.

Approach 2 (assembly language, C, perhaps some others): you
can allow signed and unsigned arithmetic, and allow
implicit type-casting to take care of the issues involved
in expressions that mix signed and unsigned quantities.
This laissez-faire approach does in fact work (on most but
not all hardware) for your simple example; but, more
generally, it leads to two major problems:
 (a) Code portability: the implicit type-casting is
     highly machine-dependent.  If I has the value -1,
     then INC(C,I) will decrement C on a machine with
     twos complement arithmetic, but it's not at all clear
     that it will give the same result on hardware that
     uses ones complement arithmetic, where "unsigned add"
     and "signed add" are two quite distinct operations.
 (b) Loss of type safety: once you allow this sort of thing,
     then as a side-effect you also have to allow more
     doubtful expressions, and you have to disable run-time
     overflow checking.  This means that many more programmer
     errors go undetected.

On a related topic: recently I've been doing some work
(interfacing to OS/2 system calls) which requires translating
some code from C or C++ to Modula-2.  I've discovered an
interesting little glitch in the specification of some of
the system calls (which were designed by C++ programmers).
Certain parameters have to have type "unsigned long", but
the value "-1" is used to denote some special cases.  This
illogicality remains undetected as long as you're coding
in C or C++, but becomes immediately obvious as soon as
you try to write something in Modula-2.

--

                  http://www.eng.newcastle.edu.au/ee/Moylan.html
OS/2 freeware list at
      http://www.eng.newcastle.edu.au/ee/Moylan/os2/os2info.html



Tue, 08 Dec 1998 03:00:00 GMT  
 INC(CARDINAL,INTEGER) problem


Quote:

>>I have a small problem with the INC standard procedure. As
>>you can see below, my compilers (two different Amiga M2 compilers)
>>report an error in line L1, but they have no problem with line L2.

>[..]
>>---------------------------------------------------------------
>>MODULE Inc;
>>VAR
>>   I: INTEGER;
>>   C: CARDINAL;
>>BEGIN
>>   I:= -1;
>>   C:= 99;
>>   C:= C + I;   (* L1: Compiler reports: incompatible operand type *)
>>   INC(C, I);   (* L2: Compiler compiles, RTS reports an overflow *)
>>END Inc.

>The mixing of CARDINAL and INTEGER leads to some awkward
>problems that language designers have never resolved
>satisfactorily.  Wirth tried to solve the problem (in Oberon)
>by removing CARDINAL from the language, but in my opinion
>that was a step backward.  (In my own programmming, I've
>found that CARDINAL is a very useful type to have, whereas
>INTEGER is something that I need only rarely.)  The ISO
>standardisation group tried at one time to solve the problem
>by making CARDINAL a subrange of INTEGER, although in the
>end that change didn't make it into the language.

The portable solution for the INC problem would be:

INC( C, VAL( CARDINAL, I ) );

Most M2-compilers accept an integer type for the second parameter in
the INC/DEC function. Using cardinals for OS/2 programming is unavoidable.
That's why Oberon-2 is not the ideal language for OS/2 programming,
because of its missing cardinal types.

Above mentioned INC statement usually translates into a simple
ADD or INC machine instruction for the Intel 386/486/Pentium
machines.

Juergen Neuhoff

-------------------------------------------------------
The Mill, Hill & Canterbury Group, Ltd.

CompuServe      73261,1622
CompuServe      76721,303

WWW             http://www.webcom.com/mhc/welcome.html
-------------------------------------------------------



Sat, 12 Dec 1998 03:00:00 GMT  
 INC(CARDINAL,INTEGER) problem

Quote:



>>>I have a small problem with the INC standard procedure. As
>>>you can see below, my compilers (two different Amiga M2 compilers)
>>>report an error in line L1, but they have no problem with line L2.

>>[..]
>>>---------------------------------------------------------------
>>>MODULE Inc;
>>>VAR
>>>   I: INTEGER;
>>>   C: CARDINAL;
>>>BEGIN
>>>   I:= -1;
>>>   C:= 99;
>>>   C:= C + I;   (* L1: Compiler reports: incompatible operand type *)
>>>   INC(C, I);   (* L2: Compiler compiles, RTS reports an overflow *)
>>>END Inc.

>>The mixing of CARDINAL and INTEGER leads to some awkward
>>problems that language designers have never resolved
>>satisfactorily.  Wirth tried to solve the problem (in Oberon)
>>by removing CARDINAL from the language, but in my opinion
>>that was a step backward.  (In my own programmming, I've
>>found that CARDINAL is a very useful type to have, whereas
>>INTEGER is something that I need only rarely.)  The ISO
>>standardisation group tried at one time to solve the problem
>>by making CARDINAL a subrange of INTEGER, although in the
>>end that change didn't make it into the language.

>The portable solution for the INC problem would be:
>INC( C, VAL( CARDINAL, I ) );
>Most M2-compilers accept an integer type for the second parameter in
>the INC/DEC function. Using cardinals for OS/2 programming is unavoidable.
>That's why Oberon-2 is not the ideal language for OS/2 programming,
>because of its missing cardinal types.

Some O2 implementations provide CARDINAL type(s) as an extension, or in the
SYSTEM module.

Quote:
>Above mentioned INC statement usually translates into a simple
>ADD or INC machine instruction for the Intel 386/486/Pentium
>machines.

Yeah, unless run-time checks are switched on, and compiler generates additional

code to check whether INTEGER is non-negative.

- Show quoted text -

Quote:
>Juergen Neuhoff
>-------------------------------------------------------
>The Mill, Hill & Canterbury Group, Ltd.
>CompuServe  73261,1622
>CompuServe  76721,303

>WWW         http://www.webcom.com/mhc/welcome.html
>-------------------------------------------------------



Sun, 13 Dec 1998 03:00:00 GMT  
 INC(CARDINAL,INTEGER) problem

Quote:
> The portable solution for the INC problem would be:

> INC( C, VAL( CARDINAL, I ) );

I thought that the second parameter was supposed to be a compile-time
constant?

Mark Morgan Lloyd

[Opinions above are the author's, not those of his employers or
colleagues]



Tue, 15 Dec 1998 03:00:00 GMT  
 INC(CARDINAL,INTEGER) problem

Quote:
>> The portable solution for the INC problem would be:

>> INC( C, VAL( CARDINAL, I ) );

>I thought that the second parameter was supposed to be a compile-time
>constant?

>Mark Morgan Lloyd

>[Opinions above are the author's, not those of his employers or
>colleagues]

Wirth's "Programming in M2" doesn't say anything about the type
of the second parameter for INC or DEC procedure. Hence,
Canterbury-Modula-2 accepts any integer or cardinal variable
or constant for the second parameter, as do most other M2-compilers.

Juergen Neuhoff

-------------------------------------------------------
The Mill, Hill & Canterbury Group, Ltd.

CompuServe      73261,1622
CompuServe      76721,303

WWW             http://www.webcom.com/mhc/welcome.html
-------------------------------------------------------



Wed, 16 Dec 1998 03:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. (in)compatibility between INTEGER and CARDINAL

2. (Copy) (in)compatibility between INTEGER and CARDINAL

3. CARDINAL and INTEGER number in Mod-2

4. EAI, CosmoPlayer 2.1 cardinal problem

5. Types.inc and OSUtils.inc

6. Auto inc problem

7. function problem in .inc file

8. from ORD to CARDINAL to CONVERT

9. Cardinal numbers

10. Cardinal numbers or unsigned int..

11. Typecasring SHORTCARD/CARDINAL/LONGCARD

12. Getting a CARDINAL into a zero-padded ARRAY OF CHAR

 

 
Powered by phpBB® Forum Software