Frank Heckenbach wrote:
Waldek Hebisch wrote:
The manual promises that `Integer' is the same size as C `int'. AFAIK on most 64-bit machines `int' is 32 bit. The consequences of C brain damage are rather unpleasent: -- all use of 64 bit integers became non-standard -- string length is limited to 32 bits
I'm not sure if the standard requires it to be limited to `Integer' (of course, that's a bit difficult to decide, since the standard doesn't have any bigger types). But even if we could change it (without changing `Integer'), I don't think it would be worth it, since it's only a small part of the problem.
-- spurious overflows/truncations since procision by default is limited to 32 bits
Of course only if one relies on `Integer' being 64 bits, or `Integer' being able to hold a `Pointer' value. Both are things one shouldn't do anyway.
look at:
const c = 1000*1000*1000*1000; { More readible then 1000000000000 }
the comptiler reports arithmetic overflow (I have fixed that example, but have to check if my fix did not couse bad side effects). And if we inside the compiler fall into the trap I bet that many programs will be (are) affected -- according to the standard `integer' is biggest and the only integer type that adjusts to the machine. So for example `integer' is natural choice as index type for "unlimited" arrays (as the type of schema discriminant).
But I agree that it's not nice -- especially if 32 bit operations are less inefficient, but also otherwise.
Scott Moore wrote:
To reach 32 bit operations in AMD 64, you have to use a mode prefix (from 64 bit mode). Hence, there is an instruction length penalty.
Efficiency is somewhat tricky here. On AMD64 instucions by default use 32 bit operands (but 64 bit addresses). To operate on 64 bits or to use extra registers one have to add a prefix. So 64 bit instructions are longer. But to use a number as an array index one have to extend it to 64 bits, so there are extra instructions. Also, the prefix byte encodes four extra bits, so if it is needed for one reason (say to use extra register) then the penalty is already paid.
AFAIK one of reasons that C uses 32 bit `int' was size -- limiting volume of data to process is belived to have much bigger effect then relative execution efficiency of 32 versus 64 bit instructions.
Note that C mandates wraparoud for unsigned type. Pascal has "affine" point of view, so Pascal backend is allowed to use higher precision if that is faster (but now we get what C folks give us: wraparoud).
On the other hand correcting the problem would break backwards compatibility. Simplest correction would be to say that Pascal `Integer' is equvalent to C `long'. Since on most 32-bit machines both `int' and `long' are 32 bits such a change would not affect popular systems 32-bit systems. Note that currently most m68k systems use 16-bit integers and change to 32 bits would correct many problems.
However, making `Integer' the same as C `long' also has drawbacks: -- 8 and 16 bit processors have 32-bit longs, which may be too large as default size
Does the backend support any 8 or 16 bit platform now?
In standard distribution:
8 bit : AVR 16 bit : 68HC11, H8/300S, pdp11, DSP1600, Xstormy16
there were also attempts to create z80 port.
I think that main question is if we are willing to break backwards compatibility. Since change in `Integer' size is quite serious difference we can not do this lightly.
It may be too late for a change, I'm not sure ...
As I said, I see the main problems in C interfaces (which so far rely on `Integer = int', while most other places really should not really on exact type sizes etc.). So *if* we change it, we should only change one type, something like `Integer = "undefined" in C', and `CInteger' (or whatever) = `int', so C interfaces would only have to s/Integer/CInteger/g. (And similar for `Cardinal'/`Word', even if nonstandard, but so we keep the fact that `Integer' and `Cardinal' have the same size.)
Of course, we'd also need a transition period here -- add `CInteger' now, let everyone change their interfaces (using GPC-version conditionals to avoid breaking compatibility with older GPCs), sometime change `Integer'. Unpleasant indeed ...
Let me try to estimate impact. AFAICS candidate for change are:
m68k 16 --> 32
and 64 bit targets:
alpha, s390x, ia64, ppc64, pa64, sparc64, mips64, sh, amd64
It seems that at the moment alpha and ia64 are really using 64-bit mode, but I have read that developmenet on other platforms is mostly 32 bit. I know that Mandrake included 64 bit version of gpc-20030830, and quite likely other disribution will follow (or already followed). On the other hand Mandrake version had serious bugs, and nobody complained, so the actual usage is likely to be quite small.
Similarely, m68k version was buggy (and we learned about them only thanks to Debian builds).
Also, a buch of bugs that I fixed on AMD64 were generic 64 bit bugs, so I think that at the moment usage on 64 bit machines is quite small.
I would say that now is last chance to do the change. In few month actual use on 64 bit machines is likely to grow considerably -- mostly due to AMD64 (and Intel clone :) but also ppc64 is on mass market (in new Power Macs).
While other targets also would be forced to change type names, since the types would remain the same the change shuild be painless for them.