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

EuroTcl/OpenACS 11 - 12 JULY 2024, VIENNA
Author:		Jan Nijtmans <[email protected]>
State:		Final
Type:		Project
Vote:		Done
Created:	04-Nov-2022
Tcl-Version:	8.7
Tcl-branch:	tip-648
Vote-Summary:   Accepted 6/0/0
Votes-For:      AK, FV, JN, MC, KW, SL
Votes-Against:  None
Votes-Present:  None


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.


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


This document has been placed in the public domain.