I have a cut down version of a bug I have found:-
File 1 (main.pas) =================
program main(output) ;
procedure initregcons ; external ;
var curpseudoreg : packed -32768..32767 ; external ;
begin 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.
File 2 (regabs.pas) ===================
module regabs ;
var curpseudoreg : packed -32768..32767 ; external ; var curpseudoreg : packed -32768..32767 ;
procedure initregcons ; external ;
procedure initregcons ; begin 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.
I compile them:-
gpc -Wall main.pas regabs.pas
and there are no warnings. By the way gpc -v gives:-
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.8.1/specs gpc version 20010924, based on gcc-2.8.1
When I run the program I get:-
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?
Cheers, Martin
P.S. I am testing using integer(16) for this example but I have other similar problems (different packed ranges).
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. external means defined in an other "module". curpseudoreg cannot be external both in regabs and in main. I do not know why there is not some error like "duplicate identifier" then in regabs, and why the curpseudoreg internal to regabs has the wrong size.
You can make it work as you expect with the following:
---------------------------------------------------------- main.pas =========
var curpseudoreg: packed -32768..32767; external; procedure initregcons ; external;
begin 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; Asmname 'Curpseudoreg'; procedure initregcons; Asmname 'Initregcons';
procedure initregcons; begin 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.
----------------------------------------------------------------- Only in the main they are declared external, since they are defined in regabs, but you need something to make them known outside of regabs, whence asmname with current gpc capitalisation, avoiding an other asmname in the main.
Now all this is "C in pascal" programming. Such kwirks are needed to interface C and Pascal. But better use regular pascal syntax, i.e. with EP modules since you seem to like the name:
------------------------------------------------------------------------- main.pas =========
program main(output) ;
import regabs;
begin 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 interface;
export regabs = all;
var curpseudoreg: packed -32768..32767; procedure initregcons ;
end.
module regabs implementation;
procedure initregcons ; begin 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.
--------------------------------------------------------------
Compiled with gpc -Wall main.pas --automake it works as expected also:
main: sizeof curpseudoreg=2 main: alignof curpseudoreg=2 main: curpseudoreg initially set to 5 initregcons: sizeof curpseudoreg=2 initregcons: alignof curpseudoreg=2 initregcons: curpseudoreg=5 initregcons: curpseudoreg now set to 99 main: curpseudoreg=99
And you have not to worry about true asmnames, with may change some day, and invalidate all your efforts ...
Maurice
-----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:-
1. If I change packed -32768..32767 to integer(16) the problem goes away for the example given.
2. I added a writlen of the addr of curpseudoreg and it is the same address in each module (new code below).
3. 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
Martin G C Davies wrote:
-----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?
<snip>
Thanks for the analysis Maurice but I don't think it's correct for three reasons:-
- 327680 is hex 50000 so it just looks like the sizeof and alignof of 4 are
what is mucking it up.
Right, and it depends on endianness, with low endian djgpp the values of
curpseudoreg are correct, because (I presume) they are now correctly aligned.
Now it seems nevertheless to me that it is the incorrect use of two "external" declarations in main and regabs which fools gpc. The following program, modeled after demomod3.pas (in the docdemos directory), which describes non EP, gpc specific modules, avoids the asmnames by putting module and main in a single file, and has only correct external declarations in main.
------------------------------------------------------------------------------ combine.pas ============
module regabs ;
var curpseudoreg : packed -32768..32767 ;
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.
program main(output) ;
procedure initregcons ; external ; var curpseudoreg : packed -32768..32767 ; 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.
---------------------------------------------------------------------------------------
It gives correct results:
main: addr curpseudoreg=338472 main: sizeof curpseudoreg=2 main: alignof curpseudoreg=2 main: curpseudoreg initially set to 5 initregcons: addr curpseudoreg=338472 initregcons: sizeof curpseudoreg=2 initregcons: alignof curpseudoreg=2 initregcons: curpseudoreg=5 initregcons: curpseudoreg now set to 99 main: curpseudoreg=99
I cannot say more ...
Maurice