Sign in Join

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

Mailing lists / fpc-devel / 2005-04

integer, cardinal

22 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

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

Yury B.

Hello fpc-devel,

Why integer is 16-bit in default (FPC) mode?
It's ok to define it as 16-bit in BP-compatibility mode, but in FPC it should be like in delphi - natural to the platform, i.e. 32-bit for 32-bit x86... or does 64-bit platform also uses 32-bit integers as default, so that longint would be good?

Best regards, Yury

Reply by email

Jonas Maebe
to Yury B.
Yury B. wrote 5 lines
Why integer is 16-bit in default (FPC) mode? It's ok to define it as 16-bit in BP-compatibility mode, but in FPC it should be like in delphi - natural to the platform, i.e. 32-bit for 32-bit x86... or does 64-bit platform also uses 32-bit integers as default, so that longint would be good?

It would break a lot of existing code if we did that. You can perfectly define integer to be whatever you want yourself. That's also how it's done in Delphi and objfpc mode: the objpas unit is then automatically included, and this unit simply includes the following declaration:

type
   integer = longint;

Jonas

PS: on most processors, using 16 bit numbers is going to be faster than using 32 bit numbers, since they occupy less memory and thus leave more room in the cache for other stuff. Afaik, the x86 family is the only one which is handicapped when performing 16 bit calculations in 32 bit mode (and even there, some processors do not have an explicit penalty, although your code grows slightly because of the prefixes to the instructions -- but then again, this is compensated when the instruction includes a constant).

Reply by email

Yury B.
to Jonas Maebe

Hello Jonas,

you wrote
> for 32-bit x86... or does 64-bit platform also uses 32-bit integers > as default, so that longint would be good?

JM> It would break a lot of existing code if we did that. You can perfectly JM> define integer to be whatever you want yourself.

I want a kind of standard. If I don't need classes then I would prefer not using objfpc or delphi mode (in order not to include huge fcl stuff) but i want integer to be natural to the platform.

Best regards, Yury

Reply by email

Jonas Maebe
to Yury B.
Yury B. wrote 8 lines
>> for 32-bit x86... or does 64-bit platform also uses 32-bit integers >> as default, so that longint would be good? JM> It would break a lot of existing code if we did that. You can perfectly JM> define integer to be whatever you want yourself. I want a kind of standard.

I don't understand why.

If I don't need classes then I would prefer not using objfpc or delphi mode (in order not to include huge fcl stuff)

They don't include any fcl stuff by default. And with smartlinking turned on, the only extra thing you get from the objpas unit is a procedure called ResetResourceTables (and the ResourceStringTable record).

but i want integer to be natural to the platform.

Even C is now moving more and more to types with a predictable size (see all the types in C99). I think knowing how large a type is, is much more important in order to create good programs than some perceived speed gain (especially since you can easily redefine any type to be whatever you want).

Jonas

Reply by email

Ales Katona
to Jonas Maebe

Jonas Maebe wrote / napísal (a):

Show quoted text 43 lines
On 17 Apr 2005, at 09:38, Yury B. wrote: >>> for 32-bit x86... or does 64-bit platform also uses 32-bit integers >>> as default, so that longint would be good? >> > > JM> It would break a lot of existing code if we did that. You can > perfectly > JM> define integer to be whatever you want yourself. > > I want a kind of standard. I don't understand why. > If I don't need classes then I would prefer > not using objfpc or delphi mode (in order not to include huge fcl > stuff) They don't include any fcl stuff by default. And with smartlinking turned on, the only extra thing you get from the objpas unit is a procedure called ResetResourceTables (and the ResourceStringTable record). > but i want integer to be natural to the platform. Even C is now moving more and more to types with a predictable size (see all the types in C99). I think knowing how large a type is, is much more important in order to create good programs than some perceived speed gain (especially since you can easily redefine any type to be whatever you want). Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

I think that pascal typesystem requires a bit overhaul when it comes to integers.

First of all Integer should be size independent, that is, xy bits depending on the platform. All others should be specific.

Second, we should "force people in a friendly way" to use more readible names like:
sint32, uint64, etc. than "cardinal"
In a few years when 64 bits are normal, what will cardinal become? who knows..

just one big IMHO

Ales

Reply by email

Nikolay Nikolov
to Ales Katona
Ales Katona wrote 15 lines
I think that pascal typesystem requires a bit overhaul when it comes to integers. First of all Integer should be size independent, that is, xy bits depending on the platform. All others should be specific. Second, we should "force people in a friendly way" to use more readible names like: sint32, uint64, etc. than "cardinal" In a few years when 64 bits are normal, what will cardinal become? who knows.. just one big IMHO Ales

I like the way it is:

unsigned integers:
byte (8-bit)
word (16-bit)
dword (32-bit)
qword (64-bit)

and signed:
shortint (8-bit)
smallint (16-bit)
longint (32-bit)
int64 (64-bit)

The unsigned versions have either 'byte' or 'word' in their name, and the signed have 'int'. (I prefer to use 'dword' instead of 'cardinal') Even on 64-bit systems always using 64-bit integers is a waste of memory. The problem with the 16-bit int was that the range -32768..+32767 was too small, and people often needed to use 32-bit, even though it was slower. Nowadays numbers outside the range of longint are rarely needed, and when needed, one can always use int64/qword or even redefine integer to be 64-bit :)

Also using mode objfpc and delphi should be only for compatibility reasons. The overhead in using mode objfpc is almost nil. (only unit objfpc is included, and it is rather small) Now if you add uses sysutils or classes, then the program gets larger, but that has nothing to do with mode objfpc.

Reply by email

DrDiettrich
to Ales Katona: Jonas Maebe wrote / napísal (a): I think that pascal typesystem requires a bit overhaul…
Ales Katona wrote 5 lines
I think that pascal typesystem requires a bit overhaul when it comes to integers. First of all Integer should be size independent, that is, xy bits depending on the platform. All others should be specific.

I agree with an application wide integer/cardinal type, but there should exist a way to get integers of a minimum size, as required by a specific program. One may use range types for that purpose, which the compiler can extend to the next "optimal" byte count, but doing so should not result in too much range checking.

Second, we should "force people in a friendly way" to use more readible names like: sint32, uint64, etc. than "cardinal"

Not necessarily, when integer and cardinal for themselves are sufficient.

What's the reason for using explicitly sized variables, of different sizes? I can see only one purpose, in the I/O of records in binary files. But with regards to different byte orders, reading structured blocks of binary information is not portable.

In a few years when 64 bits are normal, what will cardinal become? who knows..

32 bit integers will continue to be sufficient for most purposes. Arrays with more elements are not very likely in the next few years, 64 bit integers will be restricted to few special purposes (file size).

DoDi

Reply by email

Vinzent Hoefler
to Ales Katona: Jonas Maebe wrote / napísal (a): I think that pascal typesystem requires a bit overhaul…
Ales Katona wrote
First of all Integer should be size independent, that is, xy bits depending on the platform.

I second that.

Second, we should "force people in a friendly way" to use more readible names like: sint32, uint64, etc. than "cardinal"

No. Such stuff is only needed when you do hardware-interfacing. And that's the _only_ reason someone would need types with defined bit-sizes.

In a few years when 64 bits are normal, what will cardinal become? who knows..

That's why Pascal has range types. Define the range you need, and don't use "just some type" which has the range you think you will need.

Vinzent.

Reply by email

Marco van de Voort
to Vinzent Hoefler
Show quoted text 5 lines
On Sunday 17 April 2005 10:45, Ales Katona wrote: > First of all Integer should be size independent, that is, xy bits > depending on the platform. I second that.

It is now. It just happens to be the same. However keep in mind that the strict integer=wordsize bond of the past no longer goes. On most 64-bit systems, integer is _not_ 64-bit. Mostly because it only unnecessary drives up memory consumption.

Show quoted text 7 lines
> Second, we should "force people in a friendly way" to use more > readible names like: > sint32, uint64, etc. than "cardinal" No. Such stuff is only needed when you do hardware-interfacing. And that's the _only_ reason someone would need types with defined bit-sizes.

That's a bit simplistic; Network/system interfacing, binary fileformats ?

Show quoted text 5 lines
> In a few years when 64 bits are normal, what will cardinal become? > who knows.. That's why Pascal has range types. Define the range you need, and don't use "just some type" which has the range you think you will need.

I actually tried this in a major theory it is nice However quite a lot of datastructures get written to disc sooner and later, and to get fileformats size independant, you need a lot of datastructure conversions (from records with fields that have arch dependant size to packed records with fields with fixed sized integer types).

Reply by email

Peter Vreman
to Vinzent Hoefler: I second that. No. Such stuff is only needed when you do hardware-interfacing. And that's…
Show quoted text 6 lines
On Sunday 17 April 2005 10:45, Ales Katona wrote: > First of all Integer should be size independent, that is, xy bits > depending on the platform. I second that.

This is useless. Your code and runtime checks will then vary for the kind of processor (32 or 64bit) you are compiling for. Even 'int' in C is always 4 bytes. The 'long' type is most of the time equal to the size of a pointer.

Don't expect that we change anything in this part. If you want to use an integer with the natural size of the processor you can use ptrint or ptruint.

Reply by email

Marco van de Voort
to Peter Vreman

Some notes.

This is useless. Your code and runtime checks will then vary for the kind of processor (32 or 64bit) you are compiling for. Even 'int' in C is always 4 bytes.

This is not true. Most recent 64-bit machines indeed are LP64, but e.g. several Crays are ILP64. Moreover, the C standard afaik doesn't exclude it. (but did weaken the wording on not relying on int=32bit in C99)

The 'long' type is most of the time equal to the size of a pointer.

Not in LLP64, which e.g. win64 uses. There long is kept equal in size to int, and longlong is introduced for pointer.

There are more OSes that do this btw, IIRC several commercial unices did too.

Don't expect that we change anything in this part. If you want to use an integer with the natural size of the processor you can use ptrint or ptruint.

Agree fully. Or use the new -Fa parameter which is specially for such cases.

Reply by email

Vinzent Hoefler
to Marco van de Voort: It is now. It just happens to be the same. However keep in mind that the strict…
Marco van de Voort wrote 7 lines
> On Sunday 17 April 2005 10:45, Ales Katona wrote: > > First of all Integer should be size independent, that is, xy bits > > depending on the platform. > > I second that. It is now. It just happens to be the same.

:) Ok, good point.

Show quoted text 10 lines
> > Second, we should "force people in a friendly way" to use more > > readible names like: > > sint32, uint64, etc. than "cardinal" > > No. Such stuff is only needed when you do hardware-interfacing. > And that's the _only_ reason someone would need types with defined > bit-sizes. That's a bit simplistic; Network/system interfacing, binary fileformats ?

Oh sorry, in that context, I'd call that "hardware", too. It belongs to the "outside world's" interface.

Show quoted text 8 lines
> > In a few years when 64 bits are normal, what will cardinal > > become? who knows.. > > That's why Pascal has range types. Define the range you need, and > don't use "just some type" which has the range you think you will > need. I actually tried this in a major , and I actually do this in a major on everything,

of course, but it can heavily simplify some stuff, for instance because I can use the Low and High-attribu^Wfunctions on the type which is safer than using constants, because the compiler can do the work for me.

In theory it is nice

Well, in practice it works. :-)

Show quoted text 5 lines
However quite a lot of datastructures get written to disc sooner and later, and to get fileformats size independant, you need a lot of datastructure conversions (from records with fields that have arch dependant size to packed records with fields with fixed sized integer types).

Yes, of course, that's the outside world. For instance, I have to read Image-files (and if you know TIFF, you know the beast) and have to write binary structures to a connected embedded system and there I badly need known size types, but that's about it.

Maybe, you have to do such things more often, but - no offense meant - earlier experience led me to believe that binary file formats are evil. They tend to change too often, they tend to use types that don't even survive half a decade, and even if this doesn't matter known size types won't save you from the Hell of Endianess. And if you don't have that problem, you don't have it all. ;-)

Vinzent.

Reply by email

Vinzent Hoefler
to Peter Vreman: This is useless. Your code and runtime checks will then vary for the kind of processor…
Peter Vreman wrote 7 lines
> On Sunday 17 April 2005 10:45, Ales Katona wrote: >> First of all Integer should be size independent, that is, xy bits >> depending on the platform. > > I second that. This is useless. Your code

That doesn't matter. If I'd want the same code on all platforms I'd use Java.

and runtime checks

That can indeed be a problem, especially when this size is used in intermediate calculations (in correct programs, it should not have an effect on the result or you are out of luck already. Go fix your code then.).

will then vary for the kind of processor (32 or 64bit) you are compiling for.

That's some of the reasons I personally discourage using such types unless perhaps for loop-counters where you know it will never overflow some way or another.

Even 'int' in C is always 4 bytes.

Huh? Since when? Last time I checked the C99 standard, int was only guaranteed to be able to hold the values -32767 to 32767 and that makes "int" at best a "must at least be 16 bit"-type. C doesn't even specify that that thing they call "byte" is actually the usual 8-bits wide.

The 'long' type is most of the time equal to the size of a pointer.

You say it: "Most". And on platforms where it doesn't (and I know some), code that relies on that will break. So someone would be better off to assume nothing about such types. The problem in C is: there are no range types, you are _bound_ to use some of the predefined ones.

Don't expect that we change anything in this part. If you want to use an integer with the natural size of the processor you can use ptrint or ptruint.

I think that's a bad suggestion and you know it.

Oh, but while we're at it: fpc1.9.6 still gives me the Hint, that this PtrUInt/Address-Conversion isn't portable:

| WriteLn ('Runtime error ', ExitCode,
| ' at 16#',
| SysUtils.IntToHex (PtrUint(ErrorAddr), | 2 * SizeOf (ErrorAddr)), | '#');

Is that fixed in the current version? Or am I thinking wrong when I think, this should - by definition - be portable? ;-)

Vinzent.

Reply by email

Jonas Maebe
to Vinzent Hoefler
Vinzent Hoefler wrote 11 lines
Oh, but while we're at it: fpc1.9.6 still gives me the Hint, that this PtrUInt/Address-Conversion isn't portable: | WriteLn ('Runtime error ', ExitCode, | ' at 16#', | SysUtils.IntToHex (PtrUint(ErrorAddr), | 2 * SizeOf (ErrorAddr)), | '#'); Is that fixed in the current version? Or am I thinking wrong when I think, this should - by definition - be portable? ;-)

They are, but ptrint and ptruint are just regular types. The compiler cannot know they are properly defined in each RTL unit, and you can override them to be something completely different. That's why it gave and still gives a warning.

Jonas

Reply by email

Peter Vreman
to Vinzent Hoefler: That doesn't matter. If I'd want the same code on all platforms I'd use Java. That can…
Show quoted text 11 lines
Oh, but while we're at it: fpc1.9.6 still gives me the Hint, that this PtrUInt/Address-Conversion isn't portable: | WriteLn ('Runtime error ', ExitCode, | ' at 16#', | SysUtils.IntToHex (PtrUint(ErrorAddr), | 2 * SizeOf (ErrorAddr)), | '#'); Is that fixed in the current version? Or am I thinking wrong when I think, this should - by definition - be portable? ;-)

It is only a hint. And Typecasting pointer <-> integer will always trigger such a hint. It is usefull for ppl compiling on 32bit that they need to look at thing carefully if it is what they intended. Typecasting a pointer to longint on a 64bit target will give a warning instead.

But this hint/warning is independent of the first question about integer/cardinal sizes. Please stay to the topic of the thread.

Reply by email

Marco van de Voort
to Vinzent Hoefler: :) Ok, good point. Oh sorry, in that context, I'd call that "hardware", too. It belongs to
Show quoted text 11 lines
> > That's why Pascal has range types. Define the range you need, and > > don't use "just some type" which has the range you think you will > > need. > > I actually tried this in a major app at work. Well, and I actually do this in a major on everything, of course, but it can heavily simplify some stuff, for instance because I can use the Low and High-attribu^Wfunctions on the type which is safer than using constants, because the compiler can do the work for me.

I typically use enums. They suffer from the same to-disk problem though, but that can be remedied using the proper directives.

Show quoted text 7 lines
> However quite a lot of datastructures get written to disc sooner and > later, and to get fileformats size independant, you need a lot of > datastructure conversions (from records with fields that have arch > dependant size to packed records with fields with fixed sized integer > types). Yes, of course, that's the outside world.

But if you have only business data, nearly everything is directly connected to it. One only moves the problem (from declaring types fixed size to data-spooling). And it is a lot more laborous.

Show quoted text 7 lines
For instance, I have to read Image-files (and if you know TIFF, you know the beast) and have to write binary structures to a connected embedded system and there I badly need known size types, but that's about it. Maybe, you have to do such things more often, but - no offense meant - earlier experience led me to believe that binary file formats are evil.

Textformats vary with systems too. No solution either. (e.g. encodings, lineendings and other control characters). And besides that, I'm spooling millions of objects to disc during startup and shutdown. Cooked I/O is magnitudes slower. (I work with readers/writers, text-IO output is supported for debug purposes)

Binary formats are IMHO not evil. It's more that the simple basic rule of programming applies to it, think things through thoroughly before starting, and then the best effort deals with the bulk of the problems, and for the rest make custom solutions if the problems actually arise. One simply can't tailor to every possibility without making things costly or usuable.

Some simple things:
- use endian indicators somewhere near the top of the file.
- store size of records.
- use magic numbers to detect possible problems (more a testsuite thing, but still a good thing)
- use an alignment supported by a lot of compilers. (packed, C or 4 byte)
- be a bit smart with your types, and don't have too many.

They tend to change too often, they tend to use types that don't even survive half a decade, and even if this doesn't matter known size types won't save you from the Hell of Endianess. And if you don't have that problem, you don't have it all. ;-)

How do read in EBDIC textfiles btw? And unicode files in some transient standard?

Reply by email

Vinzent Hoefler
to Jonas Maebe: They are, but ptrint and ptruint are just regular types. The compiler cannot know they…
Jonas Maebe wrote
They are, but ptrint and ptruint are just regular types. The compiler cannot know they are properly defined in each RTL unit, and you can override them to be something completely different. That's why it gave and still gives a warning.

Yep. And IMHO that is - even under the usual circumstances - just the right thing to do.

Vinzent.

Reply by email

Vinzent Hoefler
to Marco van de Voort: I typically use enums. They suffer from the same to-disk problem though, but that can be…
Marco van de Voort wrote 14 lines
> > > That's why Pascal has range types. Define the range you need, > > > and don't use "just some type" which has the range you think > > > you will need. > > > > I actually tried this in a major app at work. > > Well, and I actually do this in a major on > everything, of course, but it can heavily simplify some stuff, for > instance because I can use the Low and High-attribu^Wfunctions on > the type which is safer than using constants, because the compiler > can do the work for me. I typically use enums. They suffer from the same to-disk problem though, but that can be remedied using the proper directives.

Well, I don't think I will ever use enums to define things like frequency limits.

Show quoted text 5 lines
> Yes, of course, that's the outside world. But if you have only business data, nearly everything is directly connected to it. One only moves the problem (from declaring types fixed size to data-spooling).

Ok, in that case you're probably out of luck and have to use fixed size types in almost any case. Still, you probably want to define them separately and explicitely instead of relying on some compiler behaviour. At least that's what I do:

-- 8< -- snip --
unit

   Interfaces;

{/====================================================================\} { } { hardware interface types with specific sizes } { } { PLEASE use these types in real hardware interfacing stuff only, not } { as C-like integer replacements! } { } {\====================================================================/}

interface
type
   Signed_8    = ShortInt;  //  -2**7 .. 2**7  - 1
   Unsigned_8  = byte;      //      0 .. 2**8  - 1
   Signed_16   = SmallInt;  // -2**15 .. 2**15 - 1
   Unsigned_16 = word;      //      0 .. 2**16 - 1
   Signed_32   = LongInt;   // -2**31 .. 2**31 - 1
   Unsigned_32 = LongWord;  //      0 .. 2**32 - 1
   Signed_64   = Int64;     // -2**63 .. 2**63 - 1
   Unsigned_64 = QWord;     //      0 .. 2**64 - 1
implementation

end {Interfaces}.
-- 8< -- snip --

Alas, AFAICS there is no way to define the range and the storage size of a type independent from each other in FPC?

And it is a lot more laborous.

Well, that's not really an argument (at least not on its own). The work *can* pay off, even for pure documentation purposes.

Show quoted text 6 lines
> Maybe, you have to do such things more often, but - no offense > meant - earlier experience led me to believe that binary file > formats are evil. Textformats vary with systems too. No solution either. (e.g. encodings, lineendings and other control characters).

Well, for the lineendings you already did the job for me and anything else here is currently bound to be either pure ASCII or XML (where I can stand the bloat that comes with it ;-).

And besides that, I'm spooling millions of objects to disc during startup and shutdown. Cooked I/O is magnitudes slower. (I work with readers/writers, text-IO output is supported for debug purposes)

Yes, I think I can understand that. In that case I too would use binary formats, I guess.

Show quoted text 6 lines
Binary formats are IMHO not evil. It's more that the simple basic rule of programming applies to it, think things through thoroughly before starting, and then the best effort deals with the bulk of the problems, and for the rest make custom solutions if the problems actually arise. One simply can't tailor to every possibility without making things costly or usuable.

I kind of agree with that. My bad experience comes from the fact that (some of) the people who wrote the code I am maintaining and moved to Linux now just wasn't done that way. Binary formats where used for almost everything, nobody cared for alignment and so on... So every once in a while some internal structures changed and *kaboom* the new version couldn't read the old data.

Show quoted text 6 lines
> They tend to change too often, they tend to use types that don't > even survive half a decade, and even if this doesn't matter known > size types won't save you from the Hell of Endianess. And if you > don't have that problem, you don't have it all. ;-) How do read in EBDIC textfiles btw?

I don't, luckily our platforms don't include ancient IBM mainframes. ;-) And if they would, I'd either use COBOL or write a translation unit for it.

And unicode files in some transient standard?

Again. I don't. I just use plain old 7-Bit-ASCII. If I'd want to be non-portable, I'd use binary files, you know. ;-)

Vinzent.

Reply by email

Marco van de Voort
to Vinzent Hoefler
Show quoted text 12 lines
On Monday 18 April 2005 09:02, Marco van de Voort wrote: > > Well, and I actually do this in a major on > > everything, of course, but it can heavily simplify some stuff, for > > instance because I can use the Low and High-attribu^Wfunctions on > > the type which is safer than using constants, because the compiler > > can do the work for me. > > I typically use enums. They suffer from the same to-disk problem > though, but that can be remedied using the proper directives. Well, I don't think I will ever use enums to define things like frequency limits.

Since I don't use 16-bit systems, and frequencies above 2GHz are not my domain that is not really a problem for me.

Ok, in that case you're probably out of luck and have to use fixed size types in almost any case. Still, you probably want to define them separately and explicitely instead of relying on some compiler behaviour. At least that's what I do:

There are similar things already defined in unit ctypes. This way you can for FPC make even this unit independant of what happens with integer/qword etc, because the unit is adapted per platform.

So

{$ifdef FPC}  // 1.9.x +
  mysint8type = ctypes.cint8;
  myuint8type = ctypes.cuint8;
{$ELSE}
  // inferior compilers ( :-) )
{$endif}
Alas, AFAICS there is no way to define the range and the storage size of a type independent from each other in FPC?

No. Only 1,2,4,8 sized integer types exist, in both flavours, and in ctypes identifiers are predefined. (actually ctypes is defined as containing types for the reference C compiler on that platform for header purposes, but the size-invariant types are also defined and commonly reused)

Other sizes are rarely used (3 byte sometimes in RGB handling code), and would only unnecessarily complicate the codegeneration.

> And it is a lot more laborous. Well, that's not really an argument (at least not on its own). The work *can* pay off, even for pure documentation purposes.

IMHO not really. I'd rather spend some time on the fileformats and their docs. Such code is typically near-mechanically creating conversions for data formats, hardly worth item-per-item documentation.

Yes, I think I can understand that. In that case I too would use binary formats, I guess.

(a nice example is also the game angband. x86 savegames work on ppc systems etc, and IIRC I tried a 64-bit alpha running OpenBSD too once)

Show quoted text 6 lines
I kind of agree with that. My bad experience comes from the fact that (some of) the people who wrote the code I am maintaining and moved to Linux now just wasn't done that way. Binary formats where used for almost everything, nobody cared for alignment and so on... So every once in a while some internal structures changed and *kaboom* the new version couldn't read the old data.

IOW the problem was bad programmers, not evil binary formats ;-)

I learned a lot of the tricks with dealing with binary files in my BBS era days. This due to the 16->32bit changes, different compilers, the large amounts of versions of binary files floating around, and the danger of truncation by modem.

Adapting to endianess was only a small change.

Reply by email

Vinzent Hoefler
to Marco van de Voort
Marco van de Voort wrote 10 lines
> On Monday 18 April 2005 09:02, Marco van de Voort wrote: > > > > I typically use enums. They suffer from the same to-disk problem > > though, but that can be remedied using the proper directives. > > Well, I don't think I will ever use enums to define things like > frequency limits. Since I don't use 16-bit systems, and frequencies above 2GHz are not my domain that is not really a problem for me.

That's not what I meant. The problem arises when the actual code is wrong and the supposed limit is reached. That's what a range check really is for. :)

I consider:

|type
|   Crossfeed_Ramp = 300 .. 1000;

still more readable than the declaration of explicit constants and the use of "just some int" variables. The point is in such cases I even don't care what size any variable of that type would be, because here it simply doesn't matter. Of course, such types are definitely not useful when you want to store them in files, exactly for the same reason.

Show quoted text 12 lines
There are similar things already defined in unit ctypes. This way you can for FPC make even this unit independant of what happens with integer/qword etc, because the unit is adapted per platform. So {$ifdef FPC} // 1.9.x + mysint8type = ctypes.cint8; myuint8type = ctypes.cuint8; {$ELSE} // inferior compilers ( :-) ) {$endif}

Yeah. But I'm somehow afraid of the "C" in it. ;-)

Show quoted text 5 lines
> Alas, AFAICS there is no way to define the range and the storage > size of a type independent from each other in FPC? No. Only 1,2,4,8 sized integer types exist, in both flavours, and in ctypes identifiers are predefined.

Yes. I understand that FPC has no notion of biased representation, but sometimes it still can be useful to define a constrained type with a certain range but still give the size independently (and set it to four bytes for instance, even if the type definition itself would allow a smaller size).

Other sizes are rarely used (3 byte sometimes in RGB handling code),

Hmm, rarely, yes. Still I once had to interface to a DSP56K, which has a native word size of 24 bits.

and would only unnecessarily complicate the codegeneration.

Agreed, but usually I am looking at all that stuff from the view point of the programmer and not of the compiler-writer.

Show quoted text 9 lines
> > And it is a lot more laborous. > > Well, that's not really an argument (at least not on its own). The > work *can* pay off, even for pure documentation purposes. IMHO not really. I'd rather spend some time on the fileformats and their docs. Such code is typically near-mechanically creating conversions for data formats, hardly worth item-per-item documentation.

See my small example above. The type is almost self documenting. Some more comments would be needed, if I just declared it as word/LongInt/ $whatever or (to not introduce too many "different" types) not at all.

Show quoted text 8 lines
> I kind of agree with that. My bad experience comes from the fact > that (some of) the people who wrote the code I am maintaining and > moved to Linux now just wasn't done that way. Binary formats where > used for almost everything, nobody cared for alignment and so on... > So every once in a while some internal structures changed and > *kaboom* the new version couldn't read the old data. IOW the problem was bad programmers, not evil binary formats ;-)

If you'd like to put it that way, yes. But that's why we use Pascal (or in my case, even Ada): To protect ourselves from doing bad things too easily. :)

I learned a lot of the tricks with dealing with binary files in my BBS era days. This due to the 16->32bit changes, different compilers, the large amounts of versions of binary files floating around, and the danger of truncation by modem.

I didn't realize you were thaaaaat old. <gd&r>

Vinzent.

Reply by email

Ales Katona
to Vinzent Hoefler: I second that. No. Such stuff is only needed when you do hardware-interfacing. And that's…

Vinzent Hoefler wrote / napísal (a):

Show quoted text 43 lines
On Sunday 17 April 2005 10:45, Ales Katona wrote: >First of all Integer should be size independent, that is, xy bits >depending on the platform. > > I second that. >Second, we should "force people in a friendly way" to use more >readible names like: >sint32, uint64, etc. than "cardinal" > > No. Such stuff is only needed when you do hardware-interfacing. And that's the _only_ reason someone would need types with defined bit-sizes. >In a few years when 64 bits are normal, what will cardinal become? >who knows.. > > That's why Pascal has range types. Define the range you need, and don't use "just some type" which has the range you think you will need. Vinzent. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

And how about ABI and API compatibility?

Ales

Reply by email

Marco van de Voort
to Ales Katona
Show quoted text 10 lines
Vinzent Hoefler wrote / nap?sal (a): >>In a few years when 64 bits are normal, what will cardinal become? >>who knows.. >> >> > >That's why Pascal has range types. Define the range you need, and don't >use "just some type" which has the range you think you will need. > And how about ABI and API compatibility?

Is no problem. Simply define API's using the full types, and conversions and checks are automatic.

The mapping of subranges to sizes is automatic (and typically the size is simply the base type, integer)

Reply by email