Peter N Lewis wrote:
[snip]
{$define UInt32(s) ((Ord (substr((s),1,1)) shl 24) or (Ord (substr((s),2,1)) shl 16) or (Ord (substr((s),3,1)) shl 8) or Ord (substr((s),4,1))}
should work for s as a constant-string-literal or as a constant-identifier declared as a string-literal (presuming, of course, the string has at least four characters).
Ah, good idea! This patch should fix the crash and allow `SubStr' (and `Copy') with constant arguments in constant expressions (gale1.pas). (As usual, I've made other changes meanwhile, so I hope it will fit the 20030507 sources.)
This is good, but it does have the disadvantage/risk that it uses the input parameter four times and thus is at risk if the input parameter is a function call (which at best will be called four times and at worst will cause side effects which could introduce hideous bugs).
Provided the FourCharCode type in MacTypes.pas is changed to be a UInt32 type, I don't think there will be much, if any, need to use the macro on function call results. A reasonably sane function declaration which returns a FourCharCode result would use either MacTypes's FourCharCode type or one derived from it in declaring the function result type; therefore, the results would already be in UInt32 compatible type form and the macro wouldn't need to be used (and it wouldn't work even if one tried to use it).
When one factors in Universal Interfaces into the useage senario, I think the main, and perhap only, useage of the macro will be pretty similiar to Apple's useage of the FOUR_CHAR_CODE macro in the Universal Interfaces C headers. The macro is used just with constant string literals (to fix endian issues on the C side) and once the string literals have been macro fixed there is no need to use the macro for anything else. Given the FourCharCode type is made UInt32, the intertwined type declarations and useages in the Universal Interfaces, and compiler enforcement of type compatibility, I think there will be a very strong inducement to apply the macro to all FourCharCode constant string literals at the point where they first appear to get them converted to the UInt32 type as soon as possible and once converted kept in the UInt32 type domain. If one doesn't adopt that practice, you will be constantly beating your head against the "incompatible types error" wall. (There probably will be a need to do FourCharCode/UInt32 conversions in some instances at user I/O boundaries but for most useages in the execution environment it would be best to get the four char strings converted to the UInt32 type domain as soon as possible and then leave them in that type domain. Therefore, I think it would be a good idea to apply the macro fix to all the FourCharCode constants declared in the GPCInterfaces version of the Universal Interfaces.)
I don't suppose there is any way of making that macro work but only access the input parameter once?
The only thing I can think of is using the "declaring statement" GPC extension to create a temporary variable and then use the temporary for repeated accesses. Unfortunately, that would preclude using the macro in expressions, case constants, and parameters. In other words, in order to avoid a rarely occuring (or so I believe) worst case senario of a function call macro argument, you won't be able to use the macro in all the placees where you really have a pressing, practical need to use it.
Gale Paeper gpaeper@empirenet.com