What if you define your variable as -32767..32767, instead of -32768..32767? Does that work?
I know that the full range of a 16 bit, two's complement integer is indeed -32768..32767, but Pascal does not assume two's complement implementation, hence the range for an integer is -maxint..maxint, not -(maxint+1)..maxint. Therefore, GPC may at least in some cases regard the need for -32768 as an integer type whose maxint is 32768 or greater, in which case 16 bits would be deemed inadequate (with 32 bits chosen instead).
If the above analysis is true, then GPC has two bugs : 1. It is inconsistent about whether -32768..32767 fits within 16 bits. 2. It is allowing the "external" qualifier to circumvent checking for duplicate identifiers (as Maurice has already pointed out).
Joe.
-----Original Message----- From: Martin G C Davies [SMTP:martin.g.c.davies@ntlworld.com] Sent: Wednesday, January 16, 2002 10:54 PM To: gpc@gnu.de Subject: Re: Is this a bug or me being stupid?
-----Original Message----- From: gpc-owner@gnu.de [mailto:gpc-owner@gnu.de]On Behalf Of Maurice Lombardi Sent: 16 January 2002 10:47 To: gpc@gnu.de Subject: Re: Is this a bug or me being stupid?
Martin G C Davies wrote:
main: sizeof curpseudoreg=2 main: alignof curpseudoreg=2 main: curpseudoreg initially set to 5 initregcons: sizeof curpseudoreg=4 initregcons: alignof curpseudoreg=4 initregcons: curpseudoreg=327680 initregcons: curpseudoreg now set to 99 main: curpseudoreg=0
So the quuestion is, why is the sizeof and alignog different in the
two
modules?
They are not the same variable. You see that the values also of curpseudoreg are different.
Thanks for the analysis Maurice but I don't think it's correct for three reasons:-
- If I change packed -32768..32767 to integer(16) the problem goes away
for the example given.
- I added a writlen of the addr of curpseudoreg and it is the same
address in each module (new code below).
- 327680 is hex 50000 so it just looks like the sizeof and alignof of 4
are what is mucking it up.
Thus I still think this a gpc bug.
main.pas
program main(output) ;
procedure initregcons ; external ;
var curpseudoreg : packed -32768..32767number ; external ;
begin writeln( 'main: addr curpseudoreg=' , integer( addr( curpseudoreg ) ) ) ; writeln( 'main: sizeof curpseudoreg=' , sizeof( curpseudoreg ) ) ; writeln( 'main: alignof curpseudoreg=' , alignof( curpseudoreg ) ) ; curpseudoreg := 5 ; writeln( 'main: curpseudoreg initially set to ' , curpseudoreg ) ; initregcons ; writeln( 'main: curpseudoreg=' , curpseudoreg ) ; end.
regabs.pas
module regabs ;
var curpseudoreg : packed -32768..32767 ; external ; var curpseudoreg : packed -32768..32767 ;
procedure initregcons ; external ;
procedure initregcons ; begin writeln( 'initregcons: addr curpseudoreg=' , integer( addr( curpseudoreg ) ) ) ; writeln( 'initregcons: sizeof curpseudoreg=' , sizeof( curpseudoreg ) ) ; writeln( 'initregcons: alignof curpseudoreg=' , alignof( curpseudoreg ) ) ; writeln( 'initregcons: curpseudoreg=' , curpseudoreg ) ; curpseudoreg := 99 ; writeln( 'initregcons: curpseudoreg now set to ' , curpseudoreg ) ; end ;
end.
and the output when run is:-
main: addr curpseudoreg=522892 main: sizeof curpseudoreg=2 main: alignof curpseudoreg=2 main: curpseudoreg initially set to 5 initregcons: addr curpseudoreg=522892 initregcons: sizeof curpseudoreg=4 initregcons: alignof curpseudoreg=4 initregcons: curpseudoreg=327680 initregcons: curpseudoreg now set to 99 main: curpseudoreg=0
da Silva, Joe wrote:
What if you define your variable as -32767..32767, instead of -32768..32767? Does that work?
I know that the full range of a 16 bit, two's complement integer is indeed -32768..32767, but Pascal does not assume two's complement implementation, hence the range for an integer is -maxint..maxint, not -(maxint+1)..maxint. Therefore, GPC may at least in some cases regard the need for -32768 as an integer type whose maxint is 32768 or greater, in which case 16 bits would be deemed inadequate (with 32 bits chosen instead).
I don't think that's the case.
If the above analysis is true, then GPC has two bugs :
- It is inconsistent about whether -32768..32767 fits within 16 bits.
- It is allowing the "external" qualifier to circumvent checking for duplicate identifiers (as Maurice has already pointed out).
These are inconsistencies, though I'm not sure if you can call them bugs (I guess some will even call #2 a feature, though I'd call it a misfeature at best). After all, `external' declarations are non-standard and nowhere defined exactly (AFAIK), and also the size and layout of types is implementation dependent. A program which does such things is basically relying on undocumented behaviour.
Now, I don't think the current behaviour is very good, but I consider it a very low priority issue compared to the real bugs we have. (In particular, since `external' is meant for interfacing with C and other languages, rather than for side-stepping the module mechanism, and C doesn't have a type declaration like `packed foo .. bar', problem #1 is almost a non-issue IMHO.)
As for the duplicate declarations with `external', I'd like to disallow them in fact. I'm not sure, but the fact that GPC allows them currently may be a relic from ancient times when GPC didn't support modules/units, and this "C in Pascal programming" with header files was used as a work-around (that was before I first used GPC, so I don't know for sure; another explanation is that it's another feature that was inherited from the C compiler, and should have been disabled long time ago). I won't disable it now, so shortly before the 2.1 release, but I hope I can do it immediately afterwards (i.e., I hope there won't be protests from some of you who have millions of LOC which rely on this (mis)feature and cannot be changed for hysterical raisins etc.) ...
Actually, it seems that problem #1 is related to this. I haven't investigated it in detail, but I see it happen only when such duplicate declarations are involved. So, unless I've missed some other situations where it happens as well, the problem will simply disappear when we forbid those, so it's not worth the effort to try to fix it now I think.
BTW, Martin, is there a particular reason why you write `packed -32768..32767' rather than `Cardinal (16)' or `ShortCard'? Both alternatives don't exhibit this problem AFAICS, and at least the last one is less non-standard (i.e., no syntax extension, just another predefined identifier; though the size is not guaranteed, i.e., it might be bigger than 16 bits on some platforms).
Frank
-----Original Message----- From: gpc-owner@gnu.de [mailto:gpc-owner@gnu.de]On Behalf Of Frank Heckenbach Sent: 17 January 2002 03:23 To: gpc@gnu.de Subject: Re: Is this a bug or me being stupid?
da Silva, Joe wrote:
What if you define your variable as -32767..32767, instead of -32768..32767? Does that work?
I know that the full range of a 16 bit, two's complement integer is indeed -32768..32767, but Pascal does not assume two's complement implementation, hence the range for an integer is -maxint..maxint, not -(maxint+1)..maxint. Therefore, GPC may at least in some cases regard the need for -32768 as an integer type whose maxint is 32768 or greater, in which case 16 bits would be deemed inadequate (with 32 bits chosen instead).
I don't think that's the case.
If the above analysis is true, then GPC has two bugs :
- It is inconsistent about whether -32768..32767 fits within 16 bits.
- It is allowing the "external" qualifier to circumvent checking for duplicate identifiers (as Maurice has already pointed out).
These are inconsistencies, though I'm not sure if you can call them bugs (I guess some will even call #2 a feature, though I'd call it a misfeature at best). After all, `external' declarations are non-standard and nowhere defined exactly (AFAIK), and also the size and layout of types is implementation dependent. A program which does such things is basically relying on undocumented behaviour.
Now, I don't think the current behaviour is very good, but I consider it a very low priority issue compared to the real bugs we have.
Fair enough.
(In particular, since `external' is meant for interfacing with C and other languages, rather than for side-stepping the module mechanism, and C doesn't have a type declaration like `packed foo .. bar', problem #1 is almost a non-issue IMHO.)
As for the duplicate declarations with `external', I'd like to disallow them in fact.
The reason I use external like this is because my Pascal program (yep, a rather large 250,000 lines in 150 modules) is structured very much like a C program so every module has a "template" (as in "include" file) that advertises the "public" typedefs, variables and procedures provided by the module. So, in fact, I really have 2 sources and an include:-
regabs.template ===============
type regtype = packed -32768..32767 ;
var curpseudoreg : regtype ; external ;
procedure initregcons ; external ;
regabs.pas ==========
module regabs ;
#include "regabs.template"
var curpseudoreg : regtype ;
procedure initregcons ; begin writeln( 'initregcons: addr curpseudoreg=' , integer( addr( curpseudoreg ) ) ) ; writeln( 'initregcons: sizeof curpseudoreg=' , sizeof( curpseudoreg ) ) ; writeln( 'initregcons: alignof curpseudoreg=' , alignof( curpseudoreg ) ) ; writeln( 'initregcons: curpseudoreg=' , curpseudoreg ) ; curpseudoreg := 99 ; writeln( 'initregcons: curpseudoreg now set to ' , curpseudoreg ) ; end ;
end.
main.pas ========
program main(output) ;
#include "regabs.template"
begin writeln( 'main: addr curpseudoreg=' , integer( addr( curpseudoreg ) ) ) ; writeln( 'main: sizeof curpseudoreg=' , sizeof( curpseudoreg ) ) ; writeln( 'main: alignof curpseudoreg=' , alignof( curpseudoreg ) ) ; curpseudoreg := 5 ; writeln( 'main: curpseudoreg initially set to ' , curpseudoreg ) ; initregcons ; writeln( 'main: curpseudoreg=' , curpseudoreg ) ; end.
Thus (being most familiar with C) this seemed a very natural way to use "external" (and no-one seems to worry about it when used on procedures).
I'm not sure, but the fact that GPC allows them currently may be a relic from ancient times when GPC didn't support modules/units, and this "C in Pascal programming" with header files was used as a work-around (that was before I first used GPC, so I don't know for sure; another explanation is that it's another feature that was inherited from the C compiler, and should have been disabled long time ago). I won't disable it now, so shortly before the 2.1 release, but I hope I can do it immediately afterwards (i.e., I hope there won't be protests from some of you who have millions of LOC which rely on this (mis)feature and cannot be changed for hysterical raisins etc.) ...
I am happy for you to disable it by default - but can you allow a switch that will allow this though? Apart from this one problem the mechanism is working well for the rest of my code.
I will try to move my code to a more approved mechanism.
Actually, it seems that problem #1 is related to this. I haven't investigated it in detail, but I see it happen only when such duplicate declarations are involved. So, unless I've missed some other situations where it happens as well, the problem will simply disappear when we forbid those, so it's not worth the effort to try to fix it now I think.
BTW, Martin, is there a particular reason why you write `packed -32768..32767' rather than `Cardinal (16)' or `ShortCard'?
Cards are 0..n of course, but see below.
Both alternatives don't exhibit this problem AFAICS, and at least the last one is less non-standard (i.e., no syntax extension, just another predefined identifier; though the size is not guaranteed, i.e., it might be bigger than 16 bits on some platforms).
As I mentioned in one email using integer(16) solves this particular problem for me so I am using that at present. Thus the problem is not blocking me.
Cheers, Martin.
On 17 Jan 2002, at 10:49, Martin G C Davies wrote:
[...]
The reason I use external like this is because my Pascal program (yep, a rather large 250,000 lines in 150 modules) is structured very much like a C program so every module has a "template" (as in "include" file) that advertises the "public" typedefs, variables and procedures provided by the module. So, in fact, I really have 2 sources and an include:-
regabs.template
type regtype = packed -32768..32767 ;
var curpseudoreg : regtype ; external ;
procedure initregcons ; external ;
regabs.pas
module regabs ;
#include "regabs.template"
Two things: first, why not use a unit/module for "regabs.template" instead of an include file?; second (question for Frank and Peter) - isn't "#include" deprecated or am I wrong in thinking this?
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Author of Chief's Installer Pro for Win32 Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
Prof. A Olowofoyeku (The African Chief) wrote:
On 17 Jan 2002, at 10:49, Martin G C Davies wrote:
#include "regabs.template"
Two things: first, why not use a unit/module for "regabs.template" instead of an include file?; second (question for Frank and Peter) - isn't "#include" deprecated or am I wrong in thinking this?
Yes, it is. We suggest `{$include ...}'. But I have no intentions to drop `#include' (at least as long as it doesn't cause any problems, and I'm not aware of any).
Frank