Hi GPC crew,
I just got into a new issue in my SUN Pascal to GPC conversion process:
In SUN Pascal, one can compare records variables (of the same or compatible type, obviously) with the "=" and "<>" logical operators and obviously enough, ">=" and "<=" cannot be used to compare records, it is meaningless.
It looks that GPC does not implement records comparison. The compiler reports: invalid operands to `<>'. I consulted the ISO 10206 Standard but I don't find anything about records comparison in the logical operators section. It looks like a SUN Pascal extension (one more :-() So, is there a way compare records of compatible types without doing it field by field? I know I can create new operators "=" and "<>" but in this case I will have to do it for the 600+ record types of the applications. There must be a better way to do it... In C, a simple memcmp() call could do the job :-(
However, I think this could be a nice and logical feature to have in GPC: Why, if we can assign a record to an other with ":=", cannot we test them for (in)equality afterwards?
Perhaps I am bothering you with my conversion problems and suggestions, but you already saved me hundreds hours of work. It is invaluable!
Thanks and thanks
Pascal Viandier pascal@accovia.com
Pascal Viandier wrote:
Hi GPC crew,
I just got into a new issue in my SUN Pascal to GPC conversion process:
In SUN Pascal, one can compare records variables (of the same or compatible type, obviously) with the "=" and "<>" logical operators and obviously enough, ">=" and "<=" cannot be used to compare records, it is meaningless.
It looks that GPC does not implement records comparison. The compiler reports: invalid operands to `<>'. I consulted the ISO 10206 Standard but I don't find anything about records comparison in the logical operators section. It looks like a SUN Pascal extension (one more :-() So, is there a way compare records of compatible types without doing it field by field? I know I can create new operators "=" and "<>" but in this case I will have to do it for the 600+ record types of the applications. There must be a better way to do it... In C, a simple memcmp() call could do the job :-(
You can call memcmp from Pascal also, but what about pad bytes and pad bits ? When there are pad bytes and bits, records can exist that are logically the same, but with different memory layouts ...
Regards,
Adriaan van Os
Hi,
When I say "compatible types", I say records with the same fields in the same order so I presume the padding bits and bytes would be done the same way. In fact, my exact need is to be able to compare records of the same type but if something can be done about that, it must be seen in a more generic way.
Now, for the memcmp() call, can I do it directly in my Pascal code? I used to call C code from Pascal through Pascal declarations and a C module to make the implementation, all with careful Pascal/C type mappings on prameters. If it is possible to call memcmp() directly, it would be a nice solution for my problem.
Thanks
Pascal Viandier pascal@accovia.com
Pascal Viandier wrote:
Hi GPC crew,
I just got into a new issue in my SUN Pascal to GPC conversion process:
In SUN Pascal, one can compare records variables (of the same or compatible type, obviously) with the "=" and "<>" logical operators and obviously enough, ">=" and "<=" cannot be used to compare records, it is meaningless.
It looks that GPC does not implement records comparison. The compiler reports: invalid operands to `<>'. I consulted the ISO 10206 Standard but I don't find anything about records comparison in the logical operators section. It looks like a SUN Pascal extension (one more :-() So, is there a way compare records of compatible types without doing it field by field? I know I can create new operators "=" and "<>" but in this case I will have to do it for the 600+ record types of the applications. There must be a better way to do it... In C, a simple memcmp() call could do the job :-(
You can call memcmp from Pascal also, but what about pad bytes and pad bits ? When there are pad bytes and bits, records can exist that are logically the same, but with different memory layouts ...
Regards,
Adriaan van Os
Pascal Viandier wrote:
When I say "compatible types", I say records with the same fields in the same order so I presume the padding bits and bytes would be done the same way.
Yes, but the pad bits and bytes can have random values ...
In fact, my exact need is to be able to compare records of the same type but if something can be done about that, it must be seen in a more generic way.
Now, for the memcmp() call, can I do it directly in my Pascal code? I used to call C code from Pascal through Pascal declarations and a C module to make the implementation, all with careful Pascal/C type mappings on prameters. If it is possible to call memcmp() directly, it would be a nice solution for my problem.
function memcmp( var b1, b2; len: Integer): CInteger; external; attribute ( name = 'memcmp');
function SameBytes( var b1, b2; size: Integer): boolean; begin SameBytes:= memcmp( b1, b2, size) = 0 end;
But you have been warned.
Regards,
Adriaan van Os
Adriaan van Os wrote:
In fact, my exact need is to be able to compare records of the same type but if something can be done about that, it must be seen in a more generic way.
Now, for the memcmp() call, can I do it directly in my Pascal code? I used to call C code from Pascal through Pascal declarations and a C module to make the implementation, all with careful Pascal/C type mappings on prameters. If it is possible to call memcmp() directly, it would be a nice solution for my problem.
function memcmp( var b1, b2; len: Integer): CInteger; external; attribute ( name = 'memcmp');
len: SizeType
But no need to declare it yourself, anyway. MemComp is declared in the GPC module already.
But you have been warned.
Indeed!
Pascal Viandier wrote:
I know I can create new operators "=" and "<>" but in this case I will have to do it for the 600+ record types of the applications. There must be a better way to do it... In C, a simple memcmp() call could do the job :-(
Out of curiosity, what kind of application is this where you have to compare more than 600 different record types for equality? In my whole code base, I probably have just a handful of such cases (which I do field by field then).
I agree only partially on this one. If I want to know if two records of the same type have the same contents, they have to be identical byte-for-byte, even on strings length and record variants. If it is not the case, they are different and that's ok like this. The real problem here is the random content of the padding. It can make "equal" records different. At least it cannot make different records equal ;-)
I don't know exactly how SUN Pascal does this, but it works. By dumping records in binary format, I have always seen binary zeroes in the padded zones.
How carefully have you tested it? Did you try global, local and heap-allocated variables? Did you intentionally garbage-fill the memory used before allocating the records (not applicable to global ones, but to local and dynamic ones, with some tricks)?
Did you try variant records? Nested variants? Writing to one (larger) variant, then changing the selector to a (smaller) variant and checking that the (now) unused memory was cleared? What about schemata or other kinds of dynamically-sized types (as Sun Pascal supports them)?
Anyway, it would be possible to make GPC generate code for a proper field-by-field comparison of records and arrays, including variant records (checking only the active variant) or strings (checking only the active characters). If would be some effort for me to implement it, and I don't have any use for it myself. But I could do it as a paid job. If it would really save you so much time, it might be worth it to you. If interested, please contact my by private mail.
Frank
Pascal Viandier wrote:
... snip ...
However, I think this could be a nice and logical feature to have in GPC: Why, if we can assign a record to an other with ":=", cannot we test them for (in)equality afterwards?
This is something that has never been available under any standard Pascal. The reason is that records can have padding and alignment portions with uncontrolled content. So the only way to compare records is with specific code, that examines each field as needed.
The same thing applies to C structures.
Hi,
I understand very well the complexity of comparing records, but the code I must convert to GPC is written in SUN Pascal 4.2 and the manual says clearly that you can test records equality with "<>" and "=". So does the code. Perhaps, the memory used for records is zero-filled at the variable instantiation, I don't know. That's true, SUN Pascal 4.2 has many extensions to the standard Pascal, and the programmers used them, so I hit walls here and there in the conversion process.
To clarify my intents, I must say that my purpose is not - and will never be - to criticize GPC in any way (I admire the project and the product) but to find the best ways to solve my conversion issues with the help of highly knowledgeable people.
And I think I am at the right place for this.
Thank to all of you.
Pascal Viandier pascal@accovia.com
Pascal Viandier wrote:
... snip ...
However, I think this could be a nice and logical feature to have in GPC: Why, if we can assign a record to an other with ":=", cannot we test them for (in)equality afterwards?
This is something that has never been available under any standard Pascal. The reason is that records can have padding and alignment portions with uncontrolled content. So the only way to compare records is with specific code, that examines each field as needed.
The same thing applies to C structures.