<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
</style>
</head>
<body class='hmmessage'>
Sorry, big mistakes, below:<BR>
<BR>
NOT sizeof(short) >= 2<BR>
NOT sizeof(long) >= 4<BR>
but rather<BR>
sizeof(short) * CHAR_BIT >= 16<BR>sizeof(long) * CHAR_BIT >= 32<BR>
<BR>
A conforming implementation, as I understand, could have:<BR>
#define CHAR_BIT 32<BR>
sizeof(char) = sizeof(short) = sizeof(int) = sizeof(long) = 1<BR>
<BR>
Though /practically/ speaking, CHAR_BIT is always 8 and what I said is true.<BR>
<BR>
You know..what is it..the Matlab model? Where everything is a 64 bit<BR>
double with >= 32 bit mantissa, therefore everything could be a double?<BR>
<BR>
- Jay<BR><BR>
<HR id=stopSpelling>
<BR>
From: jay.krell@cornell.edu<BR>To: eiserlohpp@yahoo.com; m3devel@elegosoft.com<BR>Date: Sat, 3 Jan 2009 08:04:37 +0000<BR>Subject: Re: [M3devel] long vs. INTEGER? ranges vs. word/integer?<BR><BR>
<STYLE>
.ExternalClass .EC_hmmessage P
{padding:0px;}
.ExternalClass body.EC_hmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
Oh I should have read more closely to correct more..<BR> <BR> <BR>> In "C" a<BR>> long is specified by the language spec to be an integral <BR>> type big enough to hold a pointer. Longs in "C" may be<BR>> bigger than a pointer, but they must be at least that size. <BR><BR> <BR>No. This is very false.<BR>There is (are) the standards, and there is the practical reality,<BR>and neither agree with your assertion.<BR> <BR>In "C89", ANSI C prior to C9x, the integral types are:<BR> char -- of wierd/uncertain signedness<BR> unsigned char <BR> signed char <BR> short (aka short int aka signed short ? aka signed short int) <BR> unsigned short (aka unsigned short int) <BR> int (aka signed int) <BR> unsigned (aka unsigned int) <BR> long (aka long int aka signed long int) <BR> unsigned long (aka unsigned long int) <BR><BR> <BR>limits.h #defines CHAR_BIT, the number of bits in a char (or signed char or unsigned char) <BR> <BR>CHAR_BIT must be at least 8.<BR>Practically speaking it is always exactly 8, but..perhaps not on a Cray.<BR> <BR>sizeof(char) == 1, by definition<BR> if char is more than 8 bits, then CHAR_BIT must be adjusted, not sizeof(char) <BR>sizeof(short) >= 2 <BR>sizeof(int) >= sizeof(short)<BR>sizeof(long) >= sizeof(int)<BR>sizeof(long) >= 4<BR> <BR>There are some types size_t and ptrdiff_t that I'm not sure what the standard says.<BR>Something like, size_t can hold the index for any array.<BR>However, the standard doesn't like speak of address spaces and their sizes, so just what is the maximum index for an array, I don't know.<BR> <BR>Practically speaking, size_t and ptrdiff_t are the exact same size as a pointer.<BR>Practially speaking, all pointers are of the same size. Though that isn't clear in the standard as I understand.<BR>Practically speaking, all pointers roundtrip through any pointer type, as well as size_t or ptrdiff_t.<BR> <BR>There is no relationship between long and pointers, in the standard.<BR> <BR>Practically speaking:<BR>CHAR_BIT == 8<BR>sizeof(short) == 2<BR>sizeof(int) == 4<BR>sizeof(long) == 4 in all 32bit and 64bit (and 16bit) Windows programming environments<BR>sizeof(long) == sizeof(void*) in most non-Windows programming environments<BR> <BR>C9x introduces several new types and typedefs.<BR>As I understand, many of the typedefs are in stdint.h, and many are optional.<BR> <BR>long long I presume is speced as:<BR>sizeof(long long) >= sizeof(long)<BR>sizeof(long long) >= 8<BR> <BR>Practically speaking, sizeof(long long) == 8.<BR> <BR>stdint.h goes nuts with the obvious options.<BR>It defines things like:<BR> fast_intN_t -- signed type that is "fast" and at least N bits in size <BR> fast_uintN_t -- unsigned ditto <BR> least_intN_t -- smallest integer that is at leasrt N bits in size <BR> least_uintN_t -- unsigned ditto <BR> intN_t -- signed integer exactly N bits in size <BR> uintN_t -- usigned ditto <BR> <BR> intptr_t -- signed integer exactly the size of a pointer <BR> uintptr_t -- unsigned ditto <BR> <BR>Not every type is mandatory though, and "fast" is vague.<BR> <BR>Then, they go even further, they have #defines for the printf and scanf strings for each type..I think.<BR> At least they have a bunch of #defines to abstract printf/scanf, not sure they have every single one.<BR>Boom goes the combinatorial explosion.<BR> <BR> <BR>So, personally, I think this is overkill.<BR> <BR>I think you should have just the exact sized types, plus the pointer-sized types.<BR>Throw out the "least" and "fast" types.<BR> <BR>Printf/scanf is thornier.<BR>It does seem a real problem, with no pretty solution.<BR> <BR>When I am just printing for debugging purposes, I often just hardcode %u or %lu and cast my data. I usually don't care if I lose the upper 32 bits, if they are even there, when I am just debugging.<BR> <BR>Microsoft long ago introduced %I64u and %I64d, but everyone else use something else, I guess %llu and %lld for long long, or maybe %Lu and %Ld.<BR> <BR>"long long" and %ll and "least"/"fast" are all nice and abstract, but again, I think it is all overkill in terms of abstraction.<BR> <BR>As you said, persistance formats are a large concern.<BR>Persistance formats frequently guide in-memory representations.<BR>Furthermore, I theorize that the abstractions aren't all that useful for in-memory data either.<BR>If you want your capacity to grow as address space grows, use size_t.<BR>Otherwise, pick a "reasonable" type.<BR>uint32_t is almost always reasonably efficent and offers adequate capacity.<BR>If you aren't sure, well go with uint64_t, it is still /fairly/ efficient on current 32 bit systems, offers nearly infinite capacity, and is perfectly efficient on 64bit systems..and 32bit should be trending downward..maybe.<BR>64bit is still memory-inefficient, so if you have large structs/arrays and certainly are comfy with fewer bits, use small.<BR> <BR>So..the decision isn't always trivial, but I still suspect using exactly sized types is plenty adequate, and that worrying about the other types is too much.<BR> <BR>gcc internally uses pairs of longs to portably represent 64 bits.<BR>And they also have "wide" integers -- the hosts widest integral type.<BR>I forget what they use them for, but I'm sure they are compatible with a 32 bit "wide" -- gcc is after all portable to a C compiler without long long, but probably not to a compiler with 16 bit int (unless maybe they use long everywhere in that situation? I don't know.)<BR> <BR> - Jay<BR> <BR><BR>
<HR id=EC_stopSpelling>
<BR>
<BR>From: jay.krell@cornell.edu<BR>To: eiserlohpp@yahoo.com; m3devel@elegosoft.com<BR>Subject: RE: [M3devel] long vs. INTEGER? ranges vs. word/integer?<BR>Date: Sat, 3 Jan 2009 07:45:26 +0000<BR><BR>
<STYLE>
.ExternalClass .EC_hmmessage P
{padding:0px;}
.ExternalClass body.EC_hmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
Peter, Huh? Of course not.<BR> <BR>"long long" is always exactly 64 bits, except on systems where it doesn't exist at all.<BR> <BR>There isn't really any 128 bit integer type in widespread use, aside from multi precision arithmetic libraries and such.<BR> <BR>long on Windows is always 32bits, as I said.<BR> <BR>The pointer sized types are: size_t, ptrdiff_t, ssize_t, INTEGER, and any pointer<BR> <BR>Surely sizeof(long) == sizeof(void*) was considered for Win64, but rejected due to the wider spread source incompatibility it would have caused. Yes, I know, every other 64 bit system took a different route -- Alpha, AIX, Solaris, IRIX, Darwin -- but they all probably had far less code to deal with.<BR> <BR>I have also programmed with a 16bit int, but nobody seems to care about portability to that these days/decades/centuries. If folks here want to imagine Modula-3 is portable to such a system, with 16 bit INTEGER, I am willing to entertain discussion and maybe even code as to the ramifications..maybe..<BR> <BR> - Jay<BR><BR><BR>> Date: Fri, 2 Jan 2009 22:52:26 -0800<BR>> From: eiserlohpp@<BR>> To: m3devel@<BR>> Subject: Re: [M3devel] long vs. INTEGER? ranges vs. word/integer?<BR>> <BR>> Jay,<BR>> <BR>> Please don't make size_t 128 bits in size. In "C" a<BR>> long is specified by the language spec to be an integral <BR>> type big enough to hold a pointer. Longs in "C" may be<BR>> bigger than a pointer, but they must be at least that size. <BR>> <BR>> NOTE: an int (integer) does not have that guarantee.<BR>> <BR>> In fact, I once programed on a platform (Amiga) that had<BR>> two different compilers one used 16-bits and other 32 for<BR>> their integers. You can imagine the difficulties.<BR>> <BR>> Windows machines, as you have been using, give an address<BR>> space of 32 bits to user space. This is regardless of how<BR>> much RAM it may actually have. I would expect that on a<BR>> Win64 platform, pointers are 64 bits, and "long" is also <BR>> 64 bits.<BR>> <BR>> On my AMD64_LINUX box, pointers are 64 bits, and therefore<BR>> a long is 64, and a long long is 128. The system type<BR>> size_t is 64 bits. If you attempt to map Cstddef.size_t<BR>> to 128 bits it will not only break the syscall interfaces<BR>> to the kernel, but also be a waste of space.<BR>> <BR>> From that standpoint the type definitions<BR>> size_t = Ctypes.unsigned_long;<BR>> ..., etc.<BR>> <BR>> are correct.<BR>> <BR>> Please don't define <BR>> size_t = Ctypes.unsigned_long_long;<BR>> <BR>> <BR>> The "C" include files<BR>> /usr/includes/bits/types.h<BR>> /usr/includes/bits/typesizes.h<BR>> <BR>> play preprocessor games to ensure that the ssize_t are<BR>> defined to use the "natural" word size. <BR>> <BR>> Other types get defined to fixed sizes (ie, _int32 must<BR>> always be 32 bits) otherwise external interfaces (file<BR>> formats, inodes, ..., etc) would be corrupted. For that<BR>> reason explicitly sized types need to be defined.<BR>> <BR>> Actually, GNU/Modula-2 recently defined explictly sized<BR>> types.<BR>> <BR>> <BR>> Peter Eiserloh.<BR>> <BR>> <BR>> <BR>> Date: Fri, 2 Jan 2009 23:05:24 +0000<BR>> From: Jay <jay.krell@cornell.edu><BR>> Subject: [M3devel] long vs. INTEGER? ranges vs. word/integer?<BR>> To: m3devel <m3devel@elegosoft.com>, Tony <hosking@cs.purdue.edu><BR>> Message-ID: <COL101-W1612F9835414ED341527DBE6E20@phx.gbl><BR>> Content-Type: text/plain; charset="iso-8859-1"<BR>> <BR>> <BR>> I'd like to avoid using "long" and "ulong" anywhere.<BR>> On Unix, they are always pointer sized.<BR>> On Windows, they are always 32 bits.<BR>> <BR>> This divergence of meaning I think it renders it useless.<BR>> <BR>> I believe for pointer-sized integers, the right types are any of:<BR>> unsigned: size_t, Word.T<BR>> signed: INTEGER, ssize_t, ptrdiff_t<BR>> For 32bit integers: int32_t and uint32_t, perhaps int.<BR>> <BR>> There is arguably some ambiguity if you consider 16bit platforms.<BR>> <BR>> Now, I noticed we have:<BR>> INTERFACE Cstddef;<BR>> <BR>> size_t = Ctypes.unsigned_long; ssize_t = Ctypes.long; ptrdiff_t = Ctypes.long;<BR>> <BR>> I would like to change this, either to:<BR>> <BR>> 32bits:<BR>> size_t = Ctypes.unsigned_int; ssize_t = Ctypes.int; ptrdiff_t = Ctypes.int;<BR>> <BR>> 64bits:<BR>> size_t = Ctypes.unsigned_long_long; ssize_t = Ctypes.long_long; ptrdiff_t = Ctypes.long_long;<BR>> <BR>> or portable:<BR>> size_t = Word.T; ssize_t = INTEGER; ptrdiff_t = INTEGER;<BR>> but, my question then is, why isn't the portable version already in use?<BR>> Especially for the signed types.<BR>> <BR>> I mean, you know, we have:<BR>> <BR>> 32bits/BasicCtypes:<BR>> <BR>> INTERFACE BasicCtypes;<BR>> IMPORT Word, Long;<BR>> TYPE (* the four signed integer types *) signed_char = [-16_7f-1 .. 16_7f]; short_int = [-16_7fff-1 .. 16_7fff]; int = [-16_7fffffff-1 .. 16_7fffffff]; long_int = [-16_7fffffff-1 .. 16_7fffffff];<BR>> question is, why aren't int and long_int INTEGER?<BR>> <BR>> 64bits/BasicCtypes:<BR>> <BR>> long_int = [-16_7fffffffffffffff -1 .. 16_7fffffffffffffff ]; long_long = [-16_7fffffffffffffffL-1L .. 16_7fffffffffffffffL];<BR>> <BR>> why not INTEGER?<BR>> <BR>> <BR>> <BR>> +--------------------------------------------------------+<BR>> | Peter P. Eiserloh |<BR>> +--------------------------------------------------------+<BR>> <BR>> <BR>> <BR><BR><BR><BR></body>
</html>