<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
FONT-SIZE: 10pt;
FONT-FAMILY:Tahoma
}
</style>
</head>
<body class='hmmessage'>
Very interesting.<BR>
The suggestion of one of the links is that the extra range of a full unsigned type isn't particularly needed, once you have 31 bits instead of only 15.<BR>
Now, in C, it is common to do a manual range check, and having unsigned cuts that check in half, makes it easier to get correct.<BR>
However Modula-3 does that checking for you, taking away more of the point of the full unsigned type.<BR>
So I guess there's just no need.<BR>
It might be nice to make Word.T != INTEGER though. ?<BR>
Gotta run.<BR>
 <BR>
- Jay<BR><BR><BR><BR>> Date: Mon, 2 Jun 2008 21:43:20 -0500<BR>> From: rodney.bates@wichita.edu<BR>> To: m3devel@elegosoft.com<BR>> Subject: Re: [M3devel] unsigned integers?<BR>> <BR>> It's already available, but takes a bit of care.<BR>> <BR>> Modula-2 had an INTEGER and a CARDINAL, the latter unsigned and having<BR>> full unsigned range for its word size. I think it was not fully<BR>> defined in the original language report. It turned out a semantic<BR>> nightmare. It was a nightmare to code too. Been there, done that.<BR>> <BR>> Modula-3's CARDINAL, as I'm sure everybody knows is just the positive<BR>> half range of INTEGER and behaves just like a subrange of INTEGER.<BR>> This solves a lot of problems, at the cost of taking away half the<BR>> unsigned range.<BR>> <BR>> For full-range unsigned, you use the type INTEGER, but use the<BR>> operations in interface Word. It's the same type, but different<BR>> interpretations applied to the same bit pattern. It would be a<BR>> good practice to declare things as INTEGER when they are signed<BR>> and Word.T when unsigned, but there is nothing in the language to<BR>> require it.<BR>> <BR>> In the case of addition and subtraction, builtin operators "+" and<BR>> "-" will produce the same results as Word.Plus and Word.Minus,<BR>> respectively, except that the conditions under which overflow is<BR>> detected will differ. Not that that matters much, as, AFAIK, none<BR>> of the implementations detect integer overflows anyway.<BR>> <BR>> So use INTEGER and the unary and binary operators if you want it to<BR>> be signed, and use Word.T and Word.<function> if you want it unsigned.<BR>> <BR>> Of course, you are free to assign between a variable that is being<BR>> treated as signed and one treated as unsigned any time, without any<BR>> overflow checks, unless you program them yourself. This certainly<BR>> violates the intuition about what safety means. However, on closer<BR>> look, it is not at all the same degree of unsafety as, say, arrays<BR>> going out of bounds.<BR>> <BR>> My definition of safe is that nothing can happen that cannot be<BR>> explained using only the concepts of the language. For example,<BR>> to understand what an array bounds error actually does, you would<BR>> need to know that an array actually shares memory with other variables,<BR>> code, etc., and then a huge amount about how the compiler, linker,<BR>> loader, heap allocator, etc. lay things out, along with what is<BR>> declared in all the code, including libraries you are not working on.<BR>> None of this is part of a so-called high-level language.<BR>> <BR>> The INTEGER/Word.T thing can be explained knowing about binary<BR>> twos-complement representation, which is definitely a machine-level<BR>> concept. The Word interface defines the unsigned side of it as<BR>> a language concept too, but only hints at the signed representation.<BR>> But most importantly, neither the operators nor the functions in<BR>> Word.T ever produce any values that are not meaningful in the value<BR>> set of the type.<BR>> <BR>> There is no really good linguistic solution to this problem, but<BR>> I think Modula-3's is definitely the least painful I have seen.<BR>> <BR>> <BR>> Jay wrote:<BR>> > What is the status and chance of a 32 bit integer with the range <BR>> > 0..0xFFFFFFFF and of a 64 bit integer type with range 0 .. <BR>> > 0xFFFFFFFFFFFFFFFF?<BR>> > <BR>> > <BR>> > Already available?<BR>> > Impossible to provide?<BR>> > Only available in unsafe modules?<BR>> > Only available with restricted operations in safe modules, and more <BR>> > operations in unsafe modules?<BR>> > <BR>> > <BR>> > Specifically, I think looping from 0 to N is safe -- no overflow.<BR>> > Subtracting a CARDINAL from an "UNSIGNED" is safe -- cannot overflow.<BR>> > Adding "UNSIGNED" to "UNSIGNED" is not safe -- can overflow.<BR>> > Adding or subtracting an INTEGER to "UNSIGNED" is not safe.<BR>> > Subtracting "UNSIGNED" from "UNSIGNED" is not safe -- can overflow.<BR>> > Comparing UNSIGNED to UNSIGNED for any of =, <, >, !=, is safe.<BR>> > Comparing UNSIGNED to CARDINAL or INTEGER is safe, but must be done <BR>> > carefully.<BR>> > Specifically, UNSIGNED > LAST(CARDINAL) is not equal to any CARDINAL <BR>> > or UNSIGNED.<BR>> > The unsafe operations above could be runtime checked perhaps.<BR>> > I guess that's a different larger point/dilemna -- when to allow <BR>> > potentially unsafe operations but with runtime checks vs. the compiler <BR>> > just disallowing them entirely. e.g. adding an integer to an integer is <BR>> > not even safe, but checked maybe at runtime (ok, at least assignment to <BR>> > subrange types is checked). Yes, I know I know, the runtime checks on at <BR>> > least many integer operations is yet lacking.<BR>> > <BR>> > Is there any, um, value in such a type?<BR>> > Is it just me blindly trying to cast Modula-3 as C (yes), but there's no <BR>> > actual value (uncertain)?<BR>> > <BR>> > <BR>> > Btw, I agree there's no point in this type in representing file sizes or <BR>> > offsets. They should be at least 63 bit integers. One bit doesn't buy <BR>> > much for file sizes. It might be something for address spaces though?<BR>> > <BR>> > It bugs me to define types like uintptr_t = CARDINAL or uintptr_t = <BR>> > INTEGER. It seems quite wrong.<BR>> > Perhaps the unsigned types larger than 16 bits just should not be <BR>> > defined in Cstdint. ??<BR>> > But there is already Ctypes.unsigned_int, unsigned_long_long, whose <BR>> > underlying type I think is signed, but which convention says you just <BR>> > don't do signed operations on, but which the compiler doesn't enforce, <BR>> > right?<BR>> > <BR>> > You know, maybe Word.T should not be INTEGER but this mythological <BR>> > UNSIGNED/UINT??????<BR>> > <BR>> > - Jay<BR>> <BR>> -- <BR>> -------------------------------------------------------------<BR>> Rodney M. Bates, retired assistant professor<BR>> Dept. of Computer Science, Wichita State University<BR>> Wichita, KS 67260-0083<BR>> 316-978-3922<BR>> rodney.bates@wichita.edu<BR><BR></body>
</html>