Pascal Viandier wrote:
2- Records initialization. This is most of the FillChar() calls. The records (around 600 of them) are used to map on rows of tables in an Informix database. They contain various data types and strings as well. These strings are SUN Pascal Varying[n] Of Char. Internally, there are 4 bytes indicating the current string length and an Array of n Char. Since FillChar() is called with Chr(0) on them, this actually sets the current string length to 0 and fill them with zeroes.
If you only want to set the length to 0, you can just assign the empty string (S := ''), which is more efficient than overwriting all characters. Unless you require the (unused) characters to be Chr(0) for some particular reason ...
But if you mean by "map" that the data structure must correspond to your database, then probably an EP string won't do anyway, because of the Capacity field. You can build you own data structure, containing a length field and a character array then.
In this case, I think the best approach will be to generate procedures to do the records initialization field by field and call them instead of FillChar(). With a moderate amount of work, my translation program should be able to take care of this.
Also, when trying some ways to solve my problem, I encountered a behaviour that I don't clearly understand regarding the "Capacity" field: If I FillChar() a String with Chr(0), the Capacity field is set to 0 - as expected - that's my problem :-(. Then, if I pass this string as Var parameter to a procedure, I cannot put anything in it. There is no runtime error or warning, but the string stays empty, WriteLn() does not show anything - in the procedure or after returning from it -. But, If I re-initialize the string directly (S10 := 'AAAAA' for example): 1- the Capacity field stays 0 - that's normal 2- but I can now use WriteLn() on it and it shows what I put in it ('AAAAA').
What is exactly the role of the "Capacity" field? Is this an expected behaviour?
The behaviour is undefined, as Capacity (and other schema discriminants) must not be written to. Normally GPC prohibits that, but with low-level tricks such as FillChar you can bypass normal checks. That's why such low-level tricks must be used with care.
As for the exact behaviour you observed, it might be that for direct access to the variable (not as a paramater) the compiler uses the constant known discriminant value instead of reading the actual value. If you send a test program, I could check it, but it probably won't matter much, as it's undefined behaviour anyway.
Gale Paeper wrote:
It seems to me that Extended Pascal's initial-state-specifier would be the ideal solution for your problem. Initial-state-specifiers are designed to exactly what you're try to accomplish here with you're hackish use of FillChar() and have the additional benefit of correctly initializing a variable of any Pascal type without needing to worry about the implementation pecularities.
Yes, if you actually want to initialize the character array, this could be a rather easy solution.
I believe Extended Pascal's initial-state-specifiers are supported in the latest GPC version but I haven't actual tested it.
Mostly yes. However, the feature is rather new, so please test a bit more carefully and report any bugs found.
There's one case that doesn't fully work yet: Initializers of (structures containing) variant records. There are some hairy issues there. Some cases may work, but there are still problems. So for now, better consider them not working. I'll announce in the release notes of a future version (not the next one, though) when they will really work.
Frank