From: <no...@so...> - 2000-11-22 13:53:59
|
Bug #123153, was updated on 2000-Nov-22 05:30 Here is a current snapshot of the bug. Project: Tcl Category: Other Status: Open Resolution: None Bug Group: 8.4a1 Priority: 7 Summary: Binary incompatibility of 8.4a1 (Tcl_InitHashTable) Details: The change to Tcl_Hashtables introduced by Paul Duffin (extended to allow user-defined keys, especially Tcl_Obj's) contains a chunk which essentially changes the public API in a non-compatible way. Binaries of extensions compiled against 8.4 are no longer useable with older versions of the core. The change in question is this one, in tcl.h: /* * Macro to use new extended version of Tcl_InitHashTable. */ #define Tcl_InitHashTable(tablePtr, keyType) \ Tcl_InitHashTableEx(tablePtr, keyType, NULL) The effect of this macro is, that extension developers believe to use the existing old interface (setting the stubs version to 8.1 or something!) but are quietly rerouted to the new one when compiling against 8.4. When such a binary is used with an older version of the core it will jump through a part of the stubs table which does not exist. Instant crash. This will happen even if TCL_PRESERVE_BINARY_COMPATABILITY is set during compilation of Tcl and of the extension! Example: Trf uses "Tcl_InitHashTable" during initialization, when creating its internal datastructures. Now, how to solve this ? (The (my) goal is to get an 8.4 which is not backward-incompatible). Alternatives: (1) Rewrite the macro above to query the interp about its version at runtime and to switch between the different entries in the stubs table. Advantages: Preserves compatibility and the additional semantics from the macro. Disadvantages: More complex, maybe more fragile too. (2) What happens when we remove this macro altogether ? Lets explore the possibilities: - Binary for an extension which was compiled against some older stubs aware core: Will jump through the stub table to Tcl_InitHashTable which in turn will signal Tcl_InitHashTableEx to not to initialize the new field in the structure. Sensible, as the old extension won't have allocated the memory for these. The macro has no relevance. - Binary for an extension using the extended features: This has to be compiled against 8.4., and will have to use Tcl_InitHashTableEx explicitly. The loss of the macro has no relevance. - Binary for an extension _not_ using the extended features, and which was compiled against 8.4. With the macro the core will use Tcl_InitHashTableEx with no user-defined type and therefore initialize the allocated additional fields, but not use them !. Without the macro the extension will jump Tcl_InitHashTable, therefore the additional fields are not initialized. But they are allocated, hence they will contain garbage. But as the extension does not use user-defined keys the fields won't be accessed either. At least if the macro TCL_PRESERVE_BINARY_COMPATABILITY exists during compilation of the core (see generic/tclHash.c). IMHO it should be defined by default. So the garbage will not hurt us (using the assumption that the preserve-macro is defined). So, when looking at (1) and (2) I prefer the latter. Follow-Ups: Date: 2000-Nov-22 05:59 By: dkf Comment: Do we really have to call it Tcl_InitHashTableEx? There seems to be a spate of these *Ex functions appearing in the core, and I'm not at all happy with the naming scheme. Couldn't we find a different name that actually means something, like Tcl_InitUserHashTable or something like that? ------------------------------------------------------- For detailed info, follow this link: http://sourceforge.net/bugs/?func=detailbug&bug_id=123153&group_id=10894 |