Grant Jacobs wrote:
Debugging:
No, it isn't. Why do you think it should? `Exit' is BP compatible. To stop the program use `Halt'.
My screw up, sorry. I've never used BP, btw; exit in other languages exits the program.
It would be good to see a more sensible error message generated when the compiler detects a missing parameter in the interface vs. implementation definitions of a proc/fn, e.g.
if you have:
interface
function string_eq( str1, str2 : string; ) : boolean ;
implementation
function string_eq( str1, str2 : string; caseSensitive : boolean ): boolean ; begin ... end ;
You get
undeclared identifier `caseSensitive' (first use in this routine)
Well, what *I* (since you say "you" ;-)
You know I'm not using that as a personal pronoun! ;-)
actually get (after filling in the missing parts and fixing the obvious syntax error) is this:
routine definition does not match previous declaration -> previous declaration
If you use `caseSensitive' within the body of `string_eq' (which you didn't show in the `...') you might get that other message because the second (wrong) redeclaration of the function is ignored, but the first error message is the important one. If you don't get this, please report with a full example (compilable code, compiler version, etc., as usual).
I'll look at this again when I find time. I'd like to think I use a parameter in the routine though, it'd be a rather pointless parameter otherwise!
If you do a rewrite() or reset(), do nothing with the file, but forget to close the file(s) before ending the program, malloc complains about a "deallocation of a pointer not yet allocated". I presume the post-execution mop-up doesn't handle unused files well -- ?
Again, *I* don't. A testing example (see above) would really help.
I didn't, or I'd have said so ;-) I only added the close() and the message went away. More to the point the usual things apply: I'm flat out so it'll be a while to get an example together as it'll take a while to reduce to a small e.g. (its part of a lot of code). I'm in the middle of chunk of Perl/JavaScript/CSS/HTML stuff so I don't want to further confuse my mind by going back to Pascal until this current project is done. (I don't know about other people but I find when jumping between languages too much I write an idiom from another language accidently once in a while which does no good at all. ) But hopefully I get back to it...
From the docs:
: The last optional parameter determines the block size of the file. : It is valid only for untyped files. Often 1 is a reasonable value here. : However, the existence of this parameter is a BP compatibility feature, : and in BP it defaults to 128 because of historic misdesign. Therefore, : GPC requires this parameter to be present. In `--borland-pascal' mode, : it makes it optional (like BP does), but warns about the strange : default if omitted.
I think my confusion must have come from the fact that all other other descriptions other than that for rewrite (append, reset, etc.) say its optional. They do hint to read rewrite for more details. I.e. read alone (without reading the rewrite section) the descriptions for append, etc. would be misleading. The impression I got on reading the "for more details see rewrite", was that'd it'd be more of the same in more detail, not that'd there might be something that'd contradict the text preceding it. I'd be good to add a line: "If you're using untyped files, the last parameter is essential; see rewrite for details." to the descriptions for reset, append, etc.
BTW, I must sound like I'm nitpicking (which I hate). I can't contribute easily to the docs as I'm not familiar with all the Pascal variants that have emerged and that GPC supports in various ways. All I can do is pick up the odd bit that throws me for whatever reason.
Macro expansion of __FILE__ seems to be inconsistent. In cases it expands to a full path and in others to just the local filename. It seems to be that if the file is in the local directory compared to the main program being compiled, just the filename is returned; if the source file is in another directory, a full path is returned.
What do you suggest? Always a full path?
I'd prefer a full path as that has all the info. Its easy enough to get a substring for the bits, etc.
While there is a CurrentRoutineName there is no CurrentUnitName. It'd be useful to have this for debugging writes, to indicate which source file to look for a routine in.
For this purpose __FILE__ would seem more useful (think of include files), I think.
True ;-) In that case I'd definitely prefer a full path for __FILE__ (think: alternative build directories, libraries, etc.)
[Fussy one] Macros can't do C99's #define many_arg_fn(...) some_fn( __VA_ARGS__ ) trick. The GNU C compiler does support this & its very useful for debugging writes (which, in turn, are useful for test-driven development).
I plan to rewrite the preprocessor, and deal with macro facilities in this course. For one thing, I'll surely not try hard to be C compatible (e.g., I plan to replace that `##' stuff with something more readable). I haven't had varargs macros on my list so far, but I might consider them. Any other comments? If debugging writes are the only use, I'm not sure they're justified well enough. (But I'd also have to see how hard it is to implement them.)
I'll differ with you on this on :-) :--
I like the compatibility with C as it aids porting to/from C. As you know macros are very much a part of a lot of C code, etc.
I dislike changes purely for cosmetics if it forces changes on existing code for no practical gain. I know C-style macros are ugly and can be fiddly to code, but for me there is practicality in gpc current macro's compatibility (to whatever degree) with their C counterparts. To be fair, I suppose I could rig things up to put my code through the C pre-processor...
About varargs in macros. I don't mind that varargs might be too much work (fair enough - there aren't enough hours in the day to do the things I want to either), but saying that debugging writes aren't a good enough use to justify varargs to me is not so valid... Like debugging, testing and verification isn't important enough...?! I don't want to say too much without trying to work around their absence again, but I presume you've used varargs in this context to understand why its useful? (macros to mimic write/writeln which take multiple args are much easier, etc.) My own use of them in C is to generate output for testing scripts to compare against (code verification). These tests remain as a test suite, etc. Without varargs the output a bit limited. (more accurately it takes too much time to make all the write's needed to generate the output, so you're inclined to skimp on debugging/testing writes). That, in turn, limits the amount of testing material generated and the sensitivity of the testing material.
Grant
Grant Jacobs wrote:
Grant Jacobs wrote:
Debugging:
No, it isn't. Why do you think it should? `Exit' is BP compatible. To stop the program use `Halt'.
My screw up, sorry. I've never used BP, btw; exit in other languages exits the program.
In C, yes. (I don't know about `exit' in other languages.) In this case, I'd rather follow BP and UCSD than C, since `Exit' to leave a procedure is not really a misnomer.
actually get (after filling in the missing parts and fixing the obvious syntax error) is this:
routine definition does not match previous declaration -> previous declaration
If you use `caseSensitive' within the body of `string_eq' (which you didn't show in the `...') you might get that other message because the second (wrong) redeclaration of the function is ignored, but the first error message is the important one. If you don't get this, please report with a full example (compilable code, compiler version, etc., as usual).
I'll look at this again when I find time. I'd like to think I use a parameter in the routine though, it'd be a rather pointless parameter otherwise!
Sure, and then the second error is clear (to me). But the first one is more important, and if you don't get it, this would be a real problem.
From the docs:
: The last optional parameter determines the block size of the file. : It is valid only for untyped files. Often 1 is a reasonable value here. : However, the existence of this parameter is a BP compatibility feature, : and in BP it defaults to 128 because of historic misdesign. Therefore, : GPC requires this parameter to be present. In `--borland-pascal' mode, : it makes it optional (like BP does), but warns about the strange : default if omitted.
I think my confusion must have come from the fact that all other other descriptions other than that for rewrite (append, reset, etc.) say its optional. They do hint to read rewrite for more details. I.e. read alone (without reading the rewrite section) the descriptions for append, etc. would be misleading. The impression I got on reading the "for more details see rewrite", was that'd it'd be more of the same in more detail, not that'd there might be something that'd contradict the text preceding it. I'd be good to add a line: "If you're using untyped files, the last parameter is essential; see rewrite for details." to the descriptions for reset, append, etc.
OK, I understand the confusion. I'll try to clarify things in the next release.
BTW, I must sound like I'm nitpicking (which I hate). I can't contribute easily to the docs as I'm not familiar with all the Pascal variants that have emerged and that GPC supports in various ways. All I can do is pick up the odd bit that throws me for whatever reason.
This is also helpful (especially for such small discrepancies which are annoying and easy to fix).
Macro expansion of __FILE__ seems to be inconsistent. In cases it expands to a full path and in others to just the local filename. It seems to be that if the file is in the local directory compared to the main program being compiled, just the filename is returned; if the source file is in another directory, a full path is returned.
What do you suggest? Always a full path?
I'd prefer a full path as that has all the info. Its easy enough to get a substring for the bits, etc.
OK, I'll change that.
[Fussy one] Macros can't do C99's #define many_arg_fn(...) some_fn( __VA_ARGS__ ) trick. The GNU C compiler does support this & its very useful for debugging writes (which, in turn, are useful for test-driven development).
I plan to rewrite the preprocessor, and deal with macro facilities in this course. For one thing, I'll surely not try hard to be C compatible (e.g., I plan to replace that `##' stuff with something more readable). I haven't had varargs macros on my list so far, but I might consider them. Any other comments? If debugging writes are the only use, I'm not sure they're justified well enough. (But I'd also have to see how hard it is to implement them.)
I'll differ with you on this on :-) :--
I like the compatibility with C as it aids porting to/from C. As you know macros are very much a part of a lot of C code, etc.
I dislike changes purely for cosmetics if it forces changes on existing code for no practical gain. I know C-style macros are ugly and can be fiddly to code, but for me there is practicality in gpc current macro's compatibility (to whatever degree) with their C counterparts. To be fair, I suppose I could rig things up to put my code through the C pre-processor...
Anyway it should be possible to define C macros to the same effect, such as:
#if defined (__STDC__) || defined (ALMOST_STDC) #define CONCAT2(a,b) a##b #else #define CONCAT2(a,b) a/**/b #endif
As you see (this is an example from libiberty), the C syntax even varies between standards, so in fact many C programmers define such a common macro anyway. Making such a macro compatible to a new Pascal macro will then also be a one-time setup, so it's acceptable I hope.
About varargs in macros. I don't mind that varargs might be too much work (fair enough - there aren't enough hours in the day to do the things I want to either), but saying that debugging writes aren't a good enough use to justify varargs to me is not so valid... Like debugging, testing and verification isn't important enough...?!
I didn't mean to imply this (since I put a lot of work into maintaining GPC's test suite myself).
Rather I'm still thinking of alternatives, and how the effort required compares with implementing varargs macros (though, as I said, I'm not sure yet, how much effort the latter will be, perhaps it'll turn out rather easy). Of course you can always define `DebugWrite1', `DebugWrite2', ...
I'm looking for ways to achieve a general form with the existing capabilities. Unfortunately I haven't found any so far. The direction I'm thinking along is something like
{$define DebugWrite(X) WriteLn X}
i.e. `DebugWrite ((foo, bar, baz))' -> `WriteLn (foo, bar,baz)' (just an extra pair of parentheses needed). Unfortunately, you probably don't want to write debug information to `Output' and I see no way to get a file parameter in that macro expansion ...
So varargs macros might be justified in the end, but I'm still waiting for other arguments for both sides ...
BTW, about the C syntax, what does `__VA_ARGS__' actually stand for? I'm wondering if (if we do it in the end) we shouldn't allow to define a parameter name for the varargs instead of having such an (ugly IMHO) "magic" name.
Frank