Author: Jan Nijtmans <[email protected]>
State: Final
Type: Project
Vote: Done
Post-History:
Keywords: Tcl Tcl_GetBoolFromObj() Tcl_GetBool()
Tcl-Version: 8.7
Tcl-Branch: tip-618
Vote-Summary Accepted 5/0/0
Votes-For: FV, JN, KW, MC, SL
Votes-Against: none
Votes-Present: none
Abstract
This TIP proposes new functions Tcl_GetBoolFromObj
/Tcl_GetBool
which are the same as
Tcl_GetBooleanFromObj
/Tcl_GetBoolean
but have an additional flags
parameter, and use char
as variable type. Also accepted is the TCL_NULL_OK
flag, which is - actually - a renamed
TCL_INDEX_NULL_OK
: We wouldn't want a separate TCL_BOOL_NULL_OK
.
If Tcl_GetBooleanFromObj
/Tcl_GetBoolean
is provided the TCL_NULL_OK
flag, it can
output not only 0 or 1 but also '\xFF'. Without the TCL_NULL_OK
flag, the only
possible outcomes are 0 and 1. In Tcl, there is not much usage for the TCL_NULL_OK
,
flag but in Tk it is more common to have values which can be empty as well as 0 or 1.
E.g. the -elide
, -overstrike
and underline
options of text tags.
Rationale
The functions Tcl_GetBooleanFromObj
/Tcl_GetBoolean
store a boolean value
into a int
, which - in many cases - is overkill since 0 and 1 are the
only possible value.
With the new functions, we can do:
#include <tcl.h> char bool1; Tcl_Obj *obj = Tcl_NewStringObj("true", -1); Tcl_GetBoolFromObj(NULL, obj, 0, &bool1);
Also, the functions Tcl_GetBoolFromObj
/Tcl_GetBool
have an additional
flags
parameter. At this moment only the values 0 and TCL_NULL_OK
are allowed. Thanks to the TCL_NULL_OK
flag, we can replace
this
code in Tk with a single call to Tcl_GetBoolFromObj()
: The -elide
,
-overstrike
and -underline
options for text tags are already mentioned,
that's the intended usage of this flag.
Other flag values can be added in the future.
History
This TIP has been in vote before, with the result of only gaining one YES vote and 3 PRESENT votes. There were 2 main remarks, indicating this TIP did too many things at once, the implications of that couldn't be grasped by the voters. Therefore, the TIP has been rewritten (and the implementation simplified). The remarks were:
- "... I don't think I grok the entire implications of the discussion we had on this list about (void *) abuses".
In C, "void *" can be used when the function accepts multiple different types.
E.g. malloc()
or memcpy()
are perfect examples, but also the use of
ClientData
in Tcl is not an abuse of "void *". The caller is responsible
making sure that a pointer of the correct type is used. In the case of
Tcl_GetBoolFromObj
/Tcl_GetBool
, the function accepts any 1-, 2-, 4-
or 8-byte enum, bool or integer type. As long as the functions know
the sizeof() of the variable, no invalid memory will be addressed.
The suggestion is also done to split this into different functions depending on the sizeof() the variable. That would be possible, but then 8 new functions should be added, and - still - a "void *" should be used as last argument: possible 1-byte types could be bool, char, signed char or unsigned char. 2-byte types could be VARIANT_BOOL, wchar_t, short or unsigned short. We don't want functions for every possible type here, when the sizeof() the variable is the only thing we really care about.
- "Even after sleeping over it I find myself unable to agree to the macro shenanigans for the transmission of the size of the referenced variable, even while admiring the hackishness of it."
The implementation rewrite doesn't use macro's any more.
Implementation
Available in the tip-618
branch.
This branch targets 8.7.
Copyright
This document has been placed in the public domain.