|
From: James W. <ja...@fr...> - 2007-05-24 18:41:43
|
Roger Holmes wrote:
> I know this occurs in several places within Quesa, some of which I
> have fixed in my own copy, and Peter tried to explain the problem to
> you and failed. I have now found another occurrence and while it is
> fresh in my mind, I hope I can explain it clearly.
>
> In QuesaRenderer.h there is an enum called TQ3CSGObjectID. This has a
> final value 0xFFFFFFFF to try to force it to 32 bits. It also has an
> initial value of -1. This worked fine with CodeWarrior where 'enum
> always int' took care of it all anyway (note it is not called enum
> always UNSIGNED int).
>
> The second registration in E3Renderer_RegisterClass is:
>
>
> qd3dStatus = Q3_REGISTER_CLASS ( kQ3ClassNameAttributeCSGID,
> NULL,
> E3CSGAttribute ) ;
>
>
> This macro expands to call E3ClassTree::RegisterClass with a final
> parameter of sizeof ( E3CSGAttribute ) which is 20 in XCode (2.4) but
> is 16 on CodeWarrior.
>
> This means that when I retrieve the value of a CSGAttribute by
> passing the address of a long, it copies 8 bytes of data into my
> 'long' and corrupts whatever comes after it in memory.
>
> This is because E3CSGAttribute is:
>
> class E3CSGAttribute : public E3Attribute // This is a leaf class so
> no other classes use this,
> // so it can be here in the .c file rather than in
> // the .h file, hence all the fields can be public
> // as nobody should be including this file
> {
> Q3_CLASS_ENUMS ( kQ3AttributeTypeConstructiveSolidGeometryID,
> E3CSGAttribute, E3Attribute )
> public :
>
> TQ3CSGObjectID instanceData ;
> } ;
>
> E3Attribute is 12 bytes long and XCode adds 8 bytes for
> TQ3CSGObjectID whereas CodeWarrior only adds 4 bytes.
>
> Changing the final 0xFFFFFFFF to 0x7FFFFFFF cures the problem.
>
> I have tried 0xFFFFFFFFL, 0xFFFFFFFFU and 0xFFFFFFFFUL and none of
> them cure the problem. Changing the -1 to 0xFFFFFFFFUL makes the
> field the correct size, but probably host programs would not work
> correctly, especially if they test for less than zero. 0x7FFFFFFF
> seems to me to be the best solution.
OK, I'm convinced now. There are only a few enumerations containing
negative values: TQ3CSGObjectID, TQ3RaveVendorID, TQ3RaveEngineID,
TQ3Error, TQ3Warning, TQ3Notice. I'll fix them, though SourceForge CVS
is broken at the moment.
Incidentally, it is not clear to me whether Xcode is in compliance with
the standard. The relevant sentence is: "It is implementation-defined
which integral type is used as the underlying type for an enumeration
except that the underlying type shall not be larger than int unless the
value of an enumerator cannot fit in an int or unsigned int." Each
enumerator of TQ3CSGObjectID can fit into an int or unsigned int, but
you can't pick just one of int and unsigned int and fit every enumerator
of TQ3CSGObjectID into it.
--
James W. Walker, Innoventive Software LLC
<http://www.frameforge3d.com/>
|