Provided by: tcl8.6-doc_8.6.9+dfsg-2_all bug

NAME

       Tcl_NewObj,    Tcl_DuplicateObj,    Tcl_IncrRefCount,    Tcl_DecrRefCount,   Tcl_IsShared,
       Tcl_InvalidateStringRep - manipulate Tcl values

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 a value; must have been the result of  a  previous
                                     call to Tcl_NewObj.
_________________________________________________________________________________________________

INTRODUCTION

       This  man page presents an overview of Tcl values (called Tcl_Objs for historical reasons)
       and how they are used.  It also describes generic  procedures  for  managing  Tcl  values.
       These procedures are used to create and copy values, and increment and decrement the count
       of references (pointers) to values.  The procedures are used in conjunction with ones that
       operate    on    specific    types    of    values    such    as   Tcl_GetIntFromObj   and
       Tcl_ListObjAppendElement.  The individual procedures are described  along  with  the  data
       structures they manipulate.

       Tcl's  dual-ported  values  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 values
       behave like strings but also hold an internal representation that can be manipulated  more
       efficiently.   For example, a Tcl list is now represented as a value that holds the list's
       string representation as well as an array of pointers to the values for each list element.
       Dual-ported  values  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  values  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  values  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 value will be reflected in that string when the
       value'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  Tcl_GetStringFromObj  and
       Tcl_GetString.

       Values  are  allocated  on  the  heap  and are referenced using a pointer to their Tcl_Obj
       structure.  Values are shared as much as possible.   This  significantly  reduces  storage
       requirements because some values 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 a value's storage.

       Tcl  values  are  typed.   A  value's  internal  representation is controlled by its type.
       Several types are predefined  in  the  Tcl  core  including  integer,  double,  list,  and
       bytecode.  Extension writers can extend the set of types by defining their own Tcl_ObjType
       structs.

THE TCL_OBJ STRUCTURE

       Each Tcl value is represented by a Tcl_Obj structure which is defined as follows.

              typedef struct Tcl_Obj {
                  int refCount;
                  char *bytes;
                  int length;
                  const Tcl_ObjType *typePtr;
                  union {
                      long longValue;
                      double doubleValue;
                      void *otherValuePtr;
                      Tcl_WideInt wideValue;
                      struct {
                          void *ptr1;
                          void *ptr2;
                      } twoPtrValue;
                      struct {
                          void *ptr;
                          unsigned long value;
                      } ptrAndLongRep;
                  } internalRep;
              } Tcl_Obj;

       The bytes and the length members together hold  a  value's  UTF-8  string  representation,
       which  is  a  counted  string  not  containing null bytes (UTF-8 null characters should be
       encoded as a two byte sequence: 192, 128.)  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 byte  after  the  last  data  byte,  at  offset  length;  this  allows  string
       representations  to  be treated as conventional null-terminated C strings.  C programs use
       Tcl_GetStringFromObj and Tcl_GetString to get a value's string representation.   If  bytes
       is NULL, the string representation is invalid.

       A  value'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 a value'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 value's type to represent the value, a Tcl_WideInt
       integer, two arbitrary pointers, or a pair made up of  an  unsigned  long  integer  and  a
       pointer.

       The  refCount  member is used to tell when it is safe to free a value's storage.  It holds
       the count of active references to the value.  Maintaining the correct reference count is a
       key  responsibility  of  extension  writers.  Reference counting is discussed below in the
       section STORAGE MANAGEMENT OF VALUES.

       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
       Tcl_IncrRefCount and Tcl_IsShared instead.

       A  key  property  of  Tcl values is that they hold two representations.  A value typically
       starts out containing only a string representation: it is untyped and has a NULL  typePtr.
       A  value  containing  an  empty  string  or  a copy of a specified string is created using
       Tcl_NewObj or Tcl_NewStringObj respectively.   A  value's  string  value  is  gotten  with
       Tcl_GetStringFromObj  or Tcl_GetString and changed with Tcl_SetStringObj.  If the value is
       later passed to a procedure like  Tcl_GetIntFromObj  that  requires  a  specific  internal
       representation,  the  procedure will create one and set the value's typePtr.  The internal
       representation is computed from the string representation.  A value's two  representations
       are  duals  of  each  other: changes made to one are reflected in the other.  For example,
       Tcl_ListObjReplace will modify a value's internal representation  and  the  next  call  to
       Tcl_GetStringFromObj or Tcl_GetString will reflect that change.

       Representations are recomputed lazily for efficiency.  A change to one representation made
       by a procedure such as Tcl_ListObjReplace  is  not  reflected  immediately  in  the  other
       representation.   Instead,  the  other representation is marked invalid so that it is only
       regenerated if it is needed later.  Most C programmers never have to be concerned with how
       this  is done and simply use procedures such as Tcl_GetBooleanFromObj or Tcl_ListObjIndex.
       Programmers that implement their own value types must check  for  invalid  representations
       and mark representations invalid when necessary.  The procedure Tcl_InvalidateStringRep is
       used to mark a value's string representation invalid and to free  any  storage  associated
       with the old string representation.

       Values usually remain one type over their life, but occasionally a value must be converted
       from one type to another.  For example, a C program might build up a  string  in  a  value
       with  repeated  calls to Tcl_AppendToObj, and then call Tcl_ListObjIndex to extract a list
       element from the value.  The same value holding the same string  value  can  have  several
       different internal representations at different times.  Extension writers can also force a
       value to be converted from one type to  another  using  the  Tcl_ConvertToType  procedure.
       Only  programmers that create new value types need to be concerned about how this is done.
       A procedure defined as part of the value type's  implementation  creates  a  new  internal
       representation   for   a   value   and   changes  its  typePtr.   See  the  man  page  for
       Tcl_RegisterObjType to see how to create a new value type.

EXAMPLE OF THE LIFETIME OF A VALUE

       As an example of the lifetime of a value, consider the following sequence of commands:

              set x 123

       This assigns to x an untyped value whose bytes member points  to  123  and  length  member
       contains 3.  The value'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 value by calling Tcl_GetIntFromObj.   This
       procedure  checks  whether  the  value  is  already an integer value.  Since it is not, it
       converts the value by setting the value's internal representation to the integer  123  and
       setting  the  value's  typePtr  to  point  to  the  integer  Tcl_ObjType  structure.  Both
       representations  are  now  valid.   incr   increments   the   value's   integer   internal
       representation    then    invalidates    its    string    representation    (by    calling
       Tcl_InvalidateStringRep) since the string representation  no  longer  corresponds  to  the
       internal representation.

              puts "x is now $x"

       The  string  representation  of  x's  value  is  needed  and  is  recomputed.   The string
       representation is now 124 and both representations are again valid.

STORAGE MANAGEMENT OF VALUES

       Tcl values are allocated on the heap and are shared as much as possible to reduce  storage
       requirements.   Reference  counting  is used to determine when a value is no longer needed
       and can safely be freed.  A value just  created  by  Tcl_NewObj  or  Tcl_NewStringObj  has
       refCount  0.   The  macro  Tcl_IncrRefCount  increments  the  reference  count  when a new
       reference to the value is created.  The macro Tcl_DecrRefCount decrements the count when a
       reference is no longer needed and, if the value's reference count drops to zero, frees its
       storage.  A value shared by different code or data structures has refCount greater than 1.
       Incrementing a value's reference count ensures that it will not be freed too early or have
       its value change accidentally.

       As an example, the bytecode interpreter shares argument values between calling and  called
       Tcl  procedures  to avoid having to copy values.  It assigns the call's argument values to
       the procedure's formal parameter variables.  In doing so,  it  calls  Tcl_IncrRefCount  to
       increment  the  reference  count of each argument since there is now a new reference to it
       from the formal parameter.  When the  called  procedure  returns,  the  interpreter  calls
       Tcl_DecrRefCount  to  decrement each argument's reference count.  When a value's reference
       count drops less than or equal to  zero,  Tcl_DecrRefCount  reclaims  its  storage.   Most
       command  procedures  do not have to be concerned about reference counting since they use a
       value's value immediately and do not retain a pointer to  the  value  after  they  return.
       However,  if they do retain a pointer to a value in a data structure, they must be careful
       to increment its reference count since the retained pointer is a new reference.

       Command procedures that directly modify values such as those for lappend and linsert  must
       be  careful  to copy a shared value before changing it.  They must first check whether the
       value is shared by calling Tcl_IsShared.  If the value is shared they must copy the  value
       by  using  Tcl_DuplicateObj;  this  returns a new duplicate of the original value that has
       refCount 0.  If the value is not shared, the command procedure “owns” the  value  and  can
       safely  modify  it  directly.   For  example,  the  following  code appears in the command
       procedure that implements linsert.  This procedure modifies the list value passed to it in
       objv[1] by inserting objc-3 new elements before index.

              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 value is
       shared before incrementing the integer in its internal representation.  If it  is  shared,
       it  needs  to  duplicate the value in order to avoid accidentally changing values in other
       data structures.

SEE ALSO

       Tcl_ConvertToType(3tcl),     Tcl_GetIntFromObj(3tcl),      Tcl_ListObjAppendElement(3tcl),
       Tcl_ListObjIndex(3tcl), Tcl_ListObjReplace(3tcl), Tcl_RegisterObjType(3tcl)

KEYWORDS

       internal  representation,  value,  value  creation, value type, reference counting, string
       representation, type conversion