diff -rc aterm-1142707243.10633/aterm/aterm.c aterm/aterm/aterm.c *** aterm-1142707243.10633/aterm/aterm.c 2006-02-08 11:35:28.000000000 +0100 --- aterm/aterm/aterm.c 2006-04-25 17:10:52.000000000 +0200 *************** *** 193,198 **** --- 193,199 ---- /* that have char == 2 bytes, and sizeof(header_type) == 2 */ assert(sizeof(header_type) == sizeof(ATerm *)); assert(sizeof(header_type) >= 4); + assert(sizeof(ATerm) == sizeof(MachineWord)); /*}}} */ /*{{{ Initialize buffer */ diff -rc aterm-1142707243.10633/aterm/memory.c aterm/aterm/memory.c *** aterm-1142707243.10633/aterm/memory.c 2006-03-09 15:02:56.000000000 +0100 --- aterm/aterm/memory.c 2006-04-25 18:22:00.000000000 +0200 *************** *** 119,130 **** hash_number(tmp,3)) */ #define HASHNUMBER3(t)\ ! FINISH(COMBINE(START(((MachineWord*)t)[0]), ((MachineWord*)t)[2])) #define HASHNUMBER4(t)\ ! FINISH(COMBINE(COMBINE(START(((MachineWord*)t)[0]), \ ! ((MachineWord*)t)[2]),((MachineWord*)t)[3])) #define HASHINT(val) \ FINISH(COMBINE(START( (AT_INT<header = header; + + and then read it through a MachineWord*, e.g., + + hnr = hash_number((ATerm) protoAppl, 2); + + (hash_number walks over the term by casting it to a MachineWord*). + + However, the same clause of the C standard also specifies that you + *can* read the memory location through a union type that contains + both the original type (e.g. ATermAppl) and the type used to read + the memory location (e.g. MachineWord). That's what we do + below: we have a union of all the types that occur in the various + ATerm types. We then read the "w" element of the union. The + compiler is not allowed to assume absence of aliasing with the + other types in the union. + + A better solution would be to hash the term through a character + pointer (since *any* memory location can be legally read as a + character), but I'm too lazy right now. Performance might also + suffer if we do that. */ + + typedef union + { + MachineWord w; + header_type header; + ATerm term; + ATermList list; + int i; + double d; + void* p; + } Aliaser; + + #define GET_WORD(t, n) (((Aliaser*) (((MachineWord*) t) + n))->w) + #define HASHNUMBER3(t)\ ! FINISH(COMBINE(START(GET_WORD(t, 0)), GET_WORD(t, 2))) #define HASHNUMBER4(t)\ ! FINISH(COMBINE(COMBINE(START(GET_WORD(t, 0)), \ ! GET_WORD(t, 2)), GET_WORD(t, 3))) #define HASHINT(val) \ FINISH(COMBINE(START( (AT_INT<header = header; CHECK_HEADER(protoAppl->header); ! if (args != PROTO_APPL_ARGS) { for (i=0; iheader = header; CHECK_HEADER(protoAppl->header); ! if (args != (ATerm *) PROTO_APPL_ARGS) { for (i=0; i