SYNOPSIS
#include <tcl.h>
Tcl_Obj * Tcl_NewObj()
Tcl_Obj * Tcl_DuplicateObj(objPtr)
Tcl_IncrRefCount(objPtr)
Tcl_DecrRefCount(objPtr)
int Tcl_IsShared(objPtr)
Tcl_InvalidateStringRep(objPtr)
ARGUMENTS
- Tcl_Obj *objPtr (in)
-
Points to an object; must have been the result of a previous call to
Tcl_NewObj() .
INTRODUCTION
This reference page presents an overview of Tcl objects and how they are used.
It also describes generic procedures for managing Tcl objects.
These procedures are used to create and copy objects,
and increment and decrement the count of references (pointers) to objects.
The procedures are used in conjunction with ones
that operate on specific types of objects such as
Tcl's dual-ported objects provide a general-purpose mechanism for storing and exchanging Tcl values. They largely replace the use of strings in Tcl. For example, they are used to store variable values, command arguments, command results, and scripts. Tcl objects behave like strings but also hold an internal representation that can be manipulated more efficiently. For example, a Tcl list is now represented as an object that holds the list's string representation as well as an array of pointers to the objects for each list element. Dual-ported objects avoid most runtime type conversions. They also improve the speed of many operations since an appropriate representation is immediately available. The compiler itself uses Tcl objects to cache the instruction bytecodes resulting from compiling scripts.
The two representations are a cache of each other and are computed lazily.
That is, each representation is only computed when necessary,
it is computed from the other representation,
and, once computed, it is saved.
In addition, a change in one representation invalidates the other one.
As an example, a Tcl program doing integer calculations can
operate directly on a variable's internal machine integer
representation without having to constantly convert
between integers and strings.
Only when it needs a string representing the variable's value,
say to print it,
will the program regenerate the string representation from the integer.
Although objects contain an internal representation,
their semantics are defined in terms of strings:
an up-to-date string can always be obtained,
and any change to the object will be reflected in that string
when the object's string representation is fetched.
Because of this representation invalidation and regeneration,
it is dangerous for extension writers to access
Tcl_Obj fields directly.
It is better to access Tcl_Obj information using
procedures like
Objects are allocated on the heap and are referenced using a pointer to their Tcl_Obj structure. Objects are shared as much as possible. This significantly reduces storage requirements because some objects such as long lists are very large. Also, most Tcl values are only read and never modified. This is especially true for procedure arguments, which can be shared between the caller and the called procedure. Assignment and argument binding is done by simply assigning a pointer to the value. Reference counting is used to determine when it is safe to reclaim an object's storage.
Tcl objects are typed.
An object's internal representation is controlled by its type.
Seven types are predefined in the Tcl core
including integer, double, list, and bytecode.
Extension writers can extend the set of types
by using the procedure
THE TCL_OBJ STRUCTURE
Each Tcl object is represented by a Tcl_Obj structure which is defined as follows.
typedef struct Tcl_Obj { int refCount; char *bytes; int length; Tcl_ObjType *typePtr; union { long longValue; double doubleValue; VOID *otherValuePtr; struct { VOID *ptr1; VOID *ptr2; } twoPtrValue; } internalRep; } Tcl_Obj;
The bytes and the length members together hold
an object's string representation,
which is a counted or binary string
that may contain binary data with embedded null bytes.
bytes points to the first byte of the string representation.
The length member gives the number of bytes.
The byte array must always have a null after the last byte,
at offset length;
this allows string representations that do not contain nulls
to be treated as conventional null-terminated C strings.
C programs use
An object's type manages its internal representation. The member typePtr points to the Tcl_ObjType structure that describes the type. If typePtr is NULL, the internal representation is invalid.
The internalRep union member holds an object's internal representation. This is either a (long) integer, a double-precision floating point number, a pointer to a value containing additional information needed by the object's type to represent the object, or two arbitrary pointers.
The refCount member is used to tell when it is safe to free an object's storage. It holds the count of active references to the object. Maintaining the correct reference count is a key responsibility of extension writers. Reference counting is discussed below in the section STORAGE MANAGEMENT OF OBJECTS.
Although extension writers can directly access
the members of a Tcl_Obj structure,
it is much better to use the appropriate procedures and macros.
For example, extension writers should never
read or update refCount directly;
they should use macros such as
A key property of Tcl objects is that they hold two representations.
An object typically starts out containing only a string representation:
it is untyped and has a NULL typePtr.
An object containing an empty string or a copy of a specified string
is created using
Representations are recomputed lazily for efficiency.
A change to one representation made by a procedure
such as
Objects usually remain one type over their life,
but occasionally an object must be converted from one type to another.
For example, a C program might build up a string in an object
with repeated calls to
EXAMPLE OF THE LIFETIME OF AN OBJECT
As an example of the lifetime of an object, consider the following sequence of commands:
set x 123
This assigns to x an untyped object whose bytes member points to 123 and length member contains 3. The object's typePtr member is NULL.
puts "x is $x"
x's string representation is valid (since bytes is non-NULL) and is fetched for the command.
incr x
The incr command first gets an integer from
x's object
by calling
puts "x is now $x"
The string representation of x's object is needed and is recomputed. The string representation is now 124. and both representations are again valid.
STORAGE MANAGEMENT OF OBJECTS
Tcl objects are allocated on the heap and are shared as much as possible
to reduce storage requirements.
Reference counting is used to determine when an object is
no longer needed and can safely be freed.
An object just created by
As an example, the bytecode interpreter shares argument objects
between calling and called Tcl procedures to avoid having to copy objects.
It assigns the call's argument objects to the procedure's
formal parameter variables.
In doing so, it calls
Command procedures that directly modify objects
such as those for lappend and linsert
must be careful to
copy a shared object before changing it.
They must first check whether the object is shared
by calling
listPtr = objv[1]; if (Tcl_IsShared(listPtr)) { listPtr = Tcl_DuplicateObj(listPtr); } result = Tcl_ListObjReplace(interp, listPtr, index, 0, (objc-3), &(objv[3]));
As another example, incr's command procedure must check whether the variable's object is shared before incrementing the integer in its internal representation. If it is shared, it needs to duplicate the object in order to avoid accidently changing values in other data structures.
PORTABILITY
Windows 8.1. Windows Server 2012 R2. Windows 10. Windows Server 2016. Windows Server 2019. Windows 11. Windows Server 2022.
AVAILABILITY
PTC MKS Toolkit for Professional Developers
PTC MKS Toolkit for Enterprise Developers
PTC MKS Toolkit for Enterprise Developers 64-Bit Edition
SEE ALSO
- Functions:
Tcl_ConvertToType() ,Tcl_GetIntFromObj() ,Tcl_ListObjAppendElement() ,Tcl_ListObjIndex() ,Tcl_ListObjReplace() ,Tcl_RegisterObjType()
PTC MKS Toolkit 10.4 Documentation Build 39.