Grant Jacobs wrote:
./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?????
Surely it is an identifier. In Pascal, an identifier is any sequence of letters, numbers and underscores (subject to the syntactic restrictions) which isn't a keyword. So any type name is also an identifier.
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.
As you found out, this isn't the case.
{=>} 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".
Yes, in a situation where each unit builds on all the previous ones, that's usually what one does. Then again, there are other situations. E.g., you might have some utility units (such as some of those distributed with GPC, say StringUtils, FileUtils, RegEx, ...) which are used where they're needed; you might have some general low-level units which are used in every unit of your project; you might have some "main functionality" units which build upon each other (i.e., a basic version of something, a refined or extended version etc., or some other functionality which uses the first one); and you might have some that are parallel (different functionalities which do not require each other) which are only put together in the main program or a highest-level unit ...
I think it depends on the situation what one needs. If the compiler would automatically re-export everything imported, you'd have less choices to structure your project.
Or put, another way, I might just as well use includes to make everything one big flat program. Sorry, but I *am* frustrated!)
This would have the disadvantage that separate compilation (automake) wouldn't be possible ...
- 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.
I'm not sure if the GPC docs mention it (as usual, they're quite incomplete), but both BP (for units) and EP (for modules) are quite clean about it. EP allows for re-exporting imported identifiers, but they have to be mentioned explicitly in the `export' clause.
Long time ago, there was a short discussion about re-exporting everything from an imported unit -- not automatically, but with some explicit directive ("unit inheritance"), but AFAIK, this hasn't been pursued further yet ...
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.
Importing <> declaring. The things are declared in the interface section of the lower-level units, but not in the one of the present unit.
- 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...
Is this clear now, with the explanation what identifier means? If not, we can, of course, change the wording of the error -- perhaps drop the "identifier" and just "type name expected, `Fnames' given".
I think it would also be easy to distinguish the cases of a unknown identifier (like here), and an identifier which is not a type, if that's what confused you.
- 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"?
In your situation, as far as I understand it, it isn't declared anywhere (more precisely, in a unit which isn't imported, which is, as far as the current unit is concerned, "nowhere" ;-).
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...
Not necessary here, I think your description is quite clear.
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?)
Yes, it refers to the same module. It doesn't affect units, and it's not relevant to your problem.
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.
I don't think so. After an error, the compiled unit would be more or less wrong to unusable. Continuing with it might lead to even more obscure follow-up errors. Furthermore, the compiled unit would habe to be marked as erroneous, lest someone uses it in another compilation and gets a seemingly successful compilation. This would add more overhead.
In fact, quite a bit of work in GPC is currently spent on continuing after an error within one source file. This is extra work in the parser (syntactic recovery, still far from perfect) and in the rest of the compiler (passing around error indicators (`error_mark_node') and trapping them in the right places to avoid crashing).
I'm wondering if it wouldn't be easier to drop this all. Today's compilation times are usually short enough that one can retry after each error. But then, the current behaviour is GCC compatible, so I guess we'll have to keep it ...
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...
I don't see it claiming a type-mismatch. It speaks of a "missing type" etc. That's one of those follow-up errors I mentioned (not exactly wrong, but somewhat redundant). Certainly, we could add some more code to avoid this particular message (and dozens of other similar situations). Usually I'm happy if it doesn't crash in such situations ...
As a general rule, everything after the first error message may or may not be accurate. This will always remain true, since no compiler can guess what you really mean when there is an error.
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.
Which error messages? If you mean the above, they're not due to any automake problem.
--automake in my hands isn't so auto ;-) !
It should work, but there may be problems. It is known that the current automake is not a perfect situation, and the solution will be to replace it by a utility which has a "higher viewpoint". I'm working on this (when I get to it), so I don't think there's much point in debugging this automake problem now (if there's one) ...
Frank