Hi,
during some debugging I noticed that GPC generates very hairy code
for the `mod' operator with signed arguments. A closer look revealed
that the code contains a lot of branching on conditions which can be
determined on compile time, and most surprisingly, the value of
X mod Y is recomputed _twice_, if X is negative. (I've attached
a commented assembler dump.)
This may be partially a back-end problem (CSE?), but I feel there's
something wrong in the relevant code in gpc-common.c (…
[View More]build_pascal_binary_op)
as well. `exp1 mod exp2' gets translated into something like
exp2 <= 0 ? error :
exp1 >= 0 ? exp1 mod exp2 :
((-exp1) mod exp2) == 0 ? 0 : exp2 - (-exp1) mod exp2
This arranges that both arguments supplied to the "internal mod"
are non-negative, but this information is not passed on -- the arguments
are still declared as signed types, which apparently makes the back-end
to produce the mess it does. I've done a little test: the following
replacement for `mod', which differs from the built-in one essentially
just by the type-casts to `Cardinal',
inline operator xmod (X, Y: Integer) = Z: Integer;
begin
if Y <= 0 then RuntimeError (714);
if X >= 0 then Z := Cardinal (X) mod Y
else begin
Z := Cardinal (-X) mod Y;
if Z <> 0 then Z := Y - Z
end
end;
indeed generates a better code, it measures about 15% faster for
positive X and more than twice faster for negative X. YMMV.
If this is possible in user code, it should work in the compiler
internals as well :)
The result type of the whole `mod' expression looks dubious too.
IIUIC, `exp1 mod exp2' inherits the type of exp1. Now, the result
of `mod' is guaranteed to be nonnegative and to fit in the type of exp2
(or more precisely, it is in 0 .. High (type of (exp2)) - 1),
whereas it needn't have anything to do with the type of exp1:
consider
var
X, Z: Integer;
Y: LongInt;
begin
X := -8;
Y := High (LongInt);
Z := X mod Y { -> overflow }
end
Or am I missing something?
Emil
(BTW, where is fjf434c.pas?)
[View Less]
As you probably know, GPC currently converts all identifiers to
first letter upper-case/rest lower-case. Since this is often not
nice, I plan to change this. This would affect at least the
following things:
- error messages
- the file name chosen with `--transparent-file-names' (makes a
difference only on case-sensitive file systems, i.e. not
Dos/Windows); is this ok (to those who use this option)?
- the file name prompt with external files without binding
While I'm at it, it might be …
[View More]easy to add a warning if an identifier
is used with varying case (something like `var Foo: Integer; [...]
WriteLn (FOO)').
- Any ideas for the name of the option? (`-Widentifier-case'?)
- Default? (I suppose off, though I think I myself would prefer on.)
- Should it work across units/modules? Or should it be a tri-state
option (never/current file/global)?
Frank
--
Frank Heckenbach, frank(a)g-n-u.de, http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: 51FF C1F0 1A77 C6C2 4482 4DDC 117A 9773 7F88 1707
[View Less]
This is an *updated* version of my previous message, which I mistaken
sent to gpc-doc (my apologies). (See the bits 'Addendum' for the new
stuff I've added.)
Excuse my being frustrated. I am trying damn hard to get GPC (2.1
(20020510), based on gcc-2.95.3 20010315 (release)) to compile a
Pascal program I wrote some time ago but keep running it things I
can't make sense of. Maybe I'm being unfair, but I'll give you the
whole story just in case its something new. The latest issue I'm
…
[View More]having is a run of type vs. identifier conflict errors of the form:
./GHJ_AARegions.pas:49: type name expected, identifier `Fnames' given
./GHJ_AARegions.pas:49: warning: missing type in declaration of `Infname'
./GHJ_AARegions.pas:54: warning: parameter has incomplete type
My trouble was fnames *is* a type. It is *only* defined as a type. So
how the heck does the compiler come away thinking that its an
identifier?????
I eventually resolved this by directly 'using' modules, rather than
rely on the hierarchy (read on).
When this error occurred the GHJ_AARegions unit uses GHJFnames.
GHJFnames in turn uses GHJFiles, which is where the type fnames is
defined. (Really these two levels need to be the other way around,
but this is a legacy program I am porting, so I have to deal with
that after the port.)
Since these uses statements were within the interface section, I
presumed the definitions would propagate upwards so that they form a
hierarchy. Or, put another way, I assumed the interface of a unit is
extended by any units it uses in its interface section.
Originally, I had:
unit GHJ_AARegions ;
interface
uses GHJStdDefs, GHJStdMaths { for inrange() },
GHJttInterface { for press_return() },
GHJStrings { for get_string8() },
{=>} GHJFnames { for get_fname() },
GHJ_AAErrors, GHJ_AAUtils, GHJ_AAGlobalUnit ;
By getting GHJ_AARegions to explicitly, directly, use GHJFiles, the
compiler stopped complaining. ie. I changed the above code to:
unit GHJ_AARegions ;
interface
uses GHJStdDefs, GHJStdMaths { for inrange() },
GHJttInterface { for press_return() },
GHJStrings { for get_string8() },
{=>} GHJFiles, GHJFnames { for get_fname() },
GHJ_AAErrors, GHJ_AAUtils, GHJ_AAGlobalUnit ;
{=>} points out the offending line of source. If this is truly the
problem, then I presume there is no way of building a hierarchy of
units in GPC at present? (In this case my safest strategy is to have
every unit uses *all* the lower units directly, "just in case". Or
put, another way, I might just as well use includes to make
everything one big flat program. Sorry, but I *am* frustrated!)
Three thoughts:
1. This is the correct behaviour?: surely I should be able to use a
higher-level module and have all the lower-level modules definitions
within that higher-level module "gotten" at the same time without
have to explicitly duck behind the scenes and drag out each module???
Excuse me for asking this, but its not terribly clear from the docs,
at least on my reading of it.
Addendum: I've since seen section 6.1.8.2. The source structure of
UCSD/Borland units of the docs say "A units exports everything
declared in the interface section". This it doesn't appear to do if
we consider things in the units imported via uses.
2. Why the heck does the compiler report the message it does?
"Missing type fnames" perhaps, but since fnames is only ever defined
as a type and never as an identifier, it shouldn't be able to report
the message it did...
3. Is there any chance you can tell the user where the "identifier"
(see the error message) is defined so that in future users might have
chance of trying to second-guess just what the compiler is "thinking"?
Sorry I can't provide a full code example: I am porting a largish
program (approx. 60,000 lines of source in a dozen or so modules) and
in any event I can't understand the problem well enough to create an
example - catch-22...
Looking at the known bugs for ver. 2.1 there are a couple that might
be relevant, esp."Types declared in a module interface are not
visible in the implementation" (but does this refer to the same
module's interface section and how are units and modules related with
reference to this?)
While I'm writing, is there any chance you can make the compiler keep
trying after one unit has failed, rather than stopping at that point?
It seems that if there is even one error in a unit, the compilation
is abandoned at the end of that unit.
Now to try figure out how GPC claims a type-mismatch on something
that is definitely the same type and the type is only defined in one
place... probably the same issue, we'll see...
Addendum: Nope. It proves to be a unit issue, but a different one. It
seems that --automake doesn't "drill down". If you modify a lower
level unit, then recompile a higher-level one that uses the
lower-level unit, GPC doesn't re-compile the lower-level unit first
and instead comes out with (apparently) misleading error messages.
--automake in my hands isn't so auto ;-) !
Grant
--
-------------------------------------------------------------------
Grant Jacobs Ph.D. BioinfoTools
ph. +64 3 476 1820 (office, after 10am) PO Box 6129,
or +64 25 601 5917 (mobile) Dunedin,
gjacobs(a)bioinfotools.com NEW ZEALAND.
Bioinformatics tools: deriving knowledge from biological data
Bioinformatics tools - software development - consulting - training
Check out the website for more details: http://www.bioinfotools.com
The information contained in this mail message is confidential and
may be legally privileged. Readers of this message who are not the
intended recipient are hereby notified that any use, dissemination,
distribution or reproduction of this message is prohibited. If you
have received this message in error please notify the sender immed-
iately and destroy the original message. This applies also to any
attached documents.
[View Less]
Yesterday, I wrote a small test program and linked it against Apple's
"Carbon framework". To my surprise, it worked. So, against all
expectations, the current compiler is able to link to Apple "dylibs"
and Apple "frameworks". The compiler produces ".o" code and the
Apple-"ld" linker takes care of the rest.
This implies, that I am loosing interest in the Apple-patched GCC
compiler. Apple writes "we're not even sure what all of them [the
compiler changes] are, because the existing …
[View More]compiler has many
undocumented changes inherited from 10 years of NeXT and Apple hacking,
and nobody knows what some of them are for." This doesn't inspire
confidence.
Besides, important changes (like precompiled header support) are now
getting integrated into mainline FSF. So, I am slowly considering it an
advantage (rather than a disadvantage) that the current port is based
on mainline FSF-GCC 3.2.1. And isn't it fun to read in officlal Apple
docs for some compiler option "Not supported on Mac OS X" where the GPC
compiler actually does ....
As a further experiment, I compiled hello.pas into hello.o and tried to
link it with "mwld", the command-line version of the MetroWerks
CodeWarrior linker. Again, to my surprise, it worked. I added "hello.o"
to a CodeWarrior Project and disassembled it there. It worked. So,
maybe some day there will be a GNU Pascal compiler plug-in CodeWarrior
(not a promise, just an idea) ....
Regards,
Adriaan van Os
[View Less]
Frank,
Thanks for your reply. I've managed to cut down the module to this very short module so I just get two errors, both - prior parameter's size depends on 'A':
MODULE Test interface;
export Test=(Test_proc);
PROCEDURE Test_proc(List : ARRAY[a..b :INTEGER] OF DOUBLE);
END.
MODULE Test implementation;
PROCEDURE Test_proc;
BEGIN
List[a]:= 2.3;
List[2]:= 2.3;
END; { Test_proc }
END.
The errors correspond to each assignment although the error line is the …
[View More]declaration.
Sure enough, converting this to a unit fixes the problem:
UNIT Test;
Interface
PROCEDURE Test_proc(List : ARRAY[a..b :INTEGER] OF DOUBLE);
Implementation
PROCEDURE Test_proc;
BEGIN
List[a]:= 2.3;
List[2]:= 2.3;
END; { Test_proc }
END.
Is the module syntax illegal or is it a bug? If it is a bug, at least you can take comfort in knowing it can kill the DEC Pascal compiler too!
Regards
David Wood, QinetiQ Farnborough
The Information contained in this E-Mail and any subsequent correspondence
is private and is intended solely for the intended recipient(s).
For those other than the recipient any disclosure, copying, distribution,
or any action taken or omitted to be taken in reliance on such information
is prohibited and may be unlawful.
[View Less]
GPC supports a number of keywords that do not belong to all (or any
;-) known Pascal standards/dialects. To relieve the resulting
problems, there are currently 3 mechanisms:
- If any dialect option (`--extended-pascal' etc.) is used, all
keywords not belonging to this standard are deactivated
completely.
- Individual keywords can be disabled using `--disable-keyword'.
- Some keywords are recognized only depending on context, so
compiling a program that uses them as identifiers is still
…
[View More] possible without any of the above options.
However, the 3rd approach only works in some situations (and can
never work perfectly, since at some points there would simply be
syntactic ambiguities between certain keywords and identifiers).
I think for some words it would be easier to recognize them as
keywords only if they have no current meaning (as identifiers) in
the program, rather than turning them on and off in certain
syntactic places (which is quite error-prone and probably still has
some subtle bugs). I'm not sure if this approach will work for all
problematic keywords, but at least for some.
So this will still work:
program Foo;
var
Foo: static Integer;
begin
end.
Also this:
program Foo;
procedure Bar;
var Static: Integer;
begin
end;
var
Foo: static Integer;
begin
end.
But not this (which works now):
program Foo;
var
Static: Integer;
Foo: static Integer;
begin
end.
Do you think this would a problem? It should not affect the ability
to compile, say, EP code without `--extended-pascal' *as far as*
that's possible now, since EP code can't use `static' as a directive
(and it can't use as identifiers what are keywords in EP).
Frank
--
Frank Heckenbach, frank(a)g-n-u.de, http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: 51FF C1F0 1A77 C6C2 4482 4DDC 117A 9773 7F88 1707
[View Less]
Adriaan van Os wrote:
>
> (1) What about this: get a pointer to the first array element
> and then
> clear sizeof-array-element * array-size bytes ?
>
> (2) With modern risc processors, the time delay for
> operations on large
> data sets is typically in memory stalls, not in processor
> instructions.
> Are your records densely packed or unaligned on the processor's
> "natural" data bounds ? Did you actually try to zero the
> array in a for
> …
[View More]loop per record (with a low-level routine if you want) ? Did you
> profile the software ?
Thanks Adriaan (and Frank) for your comments. I'm pleased to say I've
sorted out all my problems (and successfully converted another 15000 lines
of DEC Pascal to gpc with approx. 2000 line changes to get around DEC
specifics - mostly the use of x:= ZERO to clear anything).
You're right - execution time wasn't the key issue. It was more to do with
the fact that I had various records with > 10 components, each element
having a unique array type. So working out the size of each record was
tedious and zeroing with loops meant coding lots of sub-loops for the arrays
within the records.
I have effectively adopted approach (1), which is in line with the fact that
my_dyn_arr^ points to the first array element already. But for simplicity,
I support Frank's suggestion that in future gpc releases, my_dyn_arr^ points
to the start of the whole schema so I can do `FillChar' on
sizeof(my_dyn_arr^) and then `Initialize' . However, is it really true that
a floating point 0.0 isn't always all zero bytes?
Regards
David Wood.
The Information contained in this E-Mail and any subsequent correspondence
is private and is intended solely for the intended recipient(s).
For those other than the recipient any disclosure, copying, distribution,
or any action taken or omitted to be taken in reliance on such information
is prohibited and may be unlawful.
[View Less]
On 12 Feb 2003 at 05:45, Frank Heckenbach wrote:
> > > But it should be possible with moderate effort to implement
> > > something like
> > >
> > > export Foo = all (FileMode => GPC_FileMode);
> > >
> > > so one won't have to name all interface declarations, but only the
> > > re-exports and renamings explicitly.
> >
> > Ok. I'd rather not touch any EP stuff (e.g., modules) at all.
> > However, if that is …
[View More]going to be the only realistic option, then I
> > guess it would have to do ...
>
> Even when QI will work sometime, I think export renaming is still the
> better solution (shorter to write, and a little more efficient), so you
> might as well get used to it. :-)
>
> As I said, the problem currently is that the syntax given above
> doesn't work yet, but you'd have to name all regular exports in the
> `export' clause as well.
>
> Any opinions (also from others interested) on whether I should add
> this feature, and if so, with the syntax above or differently?
I can't see many responses to this, so perhaps I am the only one who
needs it. The syntax that you suggest above is quite fine by me.
Best regards, The Chief
--------
Prof. Abimbola A. Olowofoyeku (The African Chief)
web: http://www.bigfoot.com/~african_chief/
[View Less]
Hi Folks,
we need to install GPC on Solaris 9 (64-bit sun). Compilation stops at the
rts part. Most probably due to the 64-bit architecture. Is there a protocol
around this?
Cheers,
miklos
Hi,
after some friendly requests and discussion, I'm planning to
implement range checking as one of the next major things in GPC
(probably in Januaray, if nothing urgent gets in between ...).
Note, I'm using "range checking" in the specific meaning I explained
recently, not generally for all kinds of runtime checks, and not
including overflow checking of arithmetic operations etc. (that will
be a separate issue).
Also, as I said before, I'll do an "easy" implementation. I'm still
not …
[View More]convinced that anything more is worth the (big) effort when the
programmer in the rare (AFAICS) cases where it matters could just as
well use explicit types etc. to avoid checks where he doesn't want
them.
Since some of you have said they'd like to help, but can't code in
the compiler itself, here are at least 2 chances:
1. Help finding all places where range checking must be applied
In mean this from a Pascal point of view, covering, of course, all
standards, dialects and extensions that GPC supports. So far I've
found the following ones:
- assignment to variables and function results,
- value parameter passing to user-defined and built-in (e.g., `Chr',
`FillChar', ...) routines,
- array indexing (R/W),
- array slice indexing (R/W),
- `for' loop bounds,
- conformant array range,
- actual schema discriminants,
- initialization of types, variables and typed constants,
- `asm' targets
2. Write test programs
Test programs should follow the guidelines in the manual. In
particular, since most of the tests will check for errors, each one
must be a separate test for each situation (each of the cases above
plus any that others of you will come up with). For a way to test
runtime errors see, e.g., fjf424d.pas.
Range checking will be on by default, and can be switched on/off
with the options `--[no-]range-checking' and the compiler directives
`{$[no-]range-checking}', and `{$R+}', `{$R-}'. A complete set of
tests should also test all of those.
If you'd like to do so, please post a short note, so several of you
won't duplicate efforts, but can coordinate.
Frank
--
Frank Heckenbach, frank(a)g-n-u.de, http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: 51FF C1F0 1A77 C6C2 4482 4DDC 117A 9773 7F88 1707
[View Less]