TIP 648: New functions Tcl_NewWideUIntObj()/Tcl_SetWideUIntObj()

Bounty program for improvements to Tcl and certain Tcl packages.
Author:		Jan Nijtmans <[email protected]>
State:		Rejected
Type:		Project
Vote:		Done
Created:	04-Nov-2022
Tcl-Version:	8.7
Tcl-branch:	tip-648
Vote-Summary:   Rejected 1/0/1
Votes-For:      JN
Votes-Against:  none
Votes-Present:  SL


In Tcl core code, you will find a few instances of the following construct:

    Tcl_WideUInt uint;
    Tcl_Obj obj = Tcl_NewWideObj((Tcl_WideInt)uint);
This is done, because there is no function which can create a Tcl_Obj with a value >= 2^63, the purpose of this TIP. As long as the value is smaller than that, the above construct works as expected. If not, the Tcl_Obj will be initialized with a negative value.

One clear example is here, even commented with a FIXME: represent as a bignum. The lack of a Tcl_NewWideUIntObj() function in Tcl 8.6 means that whenever linking a Tcl_WideUint C-variable to a Tcl variable, the Tcl variable will have a negative value if the C-variable is > WIDE_MAX. In Tcl 8.7 this is corrected already (part of the correction came in with TIP #312, the remainder came with this commit as an internal TclNewWideUIntObj macro. This TIP makes this functionality available for extensions too.


New functions Tcl_NewWideUIntObj()/Tcl_SetWideUIntObj(), which are almost the same as Tcl_NewWideIntObj()/Tcl_SetWideIntObj(), are defined and implemented. The change is that the parameter is now unsigned.

If the value of the argument is <= WIDE_MAX, the result is the same as Tcl_NewWideIntObj()/Tcl_SetWideIntObj(). The internal representation of the Tcl_Obj will be a Tcl_WideInt. But if the value is > WIDE_MAX, then a bignum Tcl_Obj will be created, representing the given (positive) value.

Also, new functions Tcl_NewIndexObj()/Tcl_SetIndexObj() are defined, where the argument is of Tcl_Size type. For Tcl 8.7 this is the same as Tcl_NewIntObj()/Tcl_SetIntObj(). For Tcl 9.0, those functions will result in a -1 Tcl_Obj if the value is TCL_INDEX_NONE or out of range. Otherwise the result is the same as Tcl_NewWideUIntObj()/Tcl_SetWideUIntObj(). Tcl_NewIndexObj()/Tcl_SetIndexObj() can be seen as the counterpart of Tcl_GetIntForIndex().


Implementation is available in the tip-648 branch of the Tcl repository.


This document has been placed in the public domain.