Tcl_Obj(3)           Tcl Library Procedures            Tcl_Obj(3)



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


     #include <tcl.h>

     Tcl_Obj *

     Tcl_Obj *






     Tcl_Obj *objPtr (in)          Points to an object; must have
                                   been  the result of a previous
                                   call to Tcl_NewObj.


     This man 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_GetIntFromObj       and
     Tcl_ListObjAppendElement.   The  individual  procedures  are
     described along with the data structures they manipulate.

     Tcl's dual-ported objects provide a general-purpose  mechan-
     ism  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

Tcl                     Last change: 8.5                        1

Tcl_Obj(3)           Tcl Library Procedures            Tcl_Obj(3)

     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

     The two representations are a cache of each  other  and  are
     computed  lazily.  That is, each representation is only com-
     puted  when  necessary,  it  is  computed  from  the   other
     representation,  and,  once computed, it is saved.  In addi-
     tion, a change in one representation invalidates  the  other
     one.   As  an  example, a Tcl program doing integer calcula-
     tions 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 representa-
     tion, 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 Tcl_GetStringFromObj and Tcl_GetString.

     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  pro-
     cedure.   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.  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.


     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                     Last change: 8.5                        2

Tcl_Obj(3)           Tcl Library Procedures            Tcl_Obj(3)

                  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  an  object'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 an object's
     string  representation.   If  bytes  is  NULL,  the   string
     representation is invalid.

     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  con-
     taining  additional  information needed by the object's type
     to represent the object, a Tcl_WideInt  integer,  two  arbi-
     trary  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
     an  object's  storage.   It holds the count of active refer-
     ences to the  object.   Maintaining  the  correct  reference
     count  is a key responsibility of extension writers.  Refer-
     ence counting is discussed  below  in  the  section  STORAGE

     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

Tcl                     Last change: 8.5                        3

Tcl_Obj(3)           Tcl Library Procedures            Tcl_Obj(3)

     writers  should never read or update refCount directly; they
     should use macros such as Tcl_IncrRefCount and  Tcl_IsShared

     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   Tcl_NewObj   or
     Tcl_NewStringObj  respectively.  An object's string value is
     gotten  with  Tcl_GetStringFromObj  or   Tcl_GetString   and
     changed  with  Tcl_SetStringObj.   If  the  object  is later
     passed to a procedure like Tcl_GetIntFromObj that requires a
     specific  internal representation, the procedure will create
     one and set the object's typePtr.  The internal  representa-
     tion   is  computed  from  the  string  representation.   An
     object's  two  representations  are  duals  of  each  other:
     changes  made  to one are reflected in the other.  For exam-
     ple, Tcl_ListObjReplace will  modify  an  object'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 object  types  must  check  for  invalid
     representations and mark representations invalid when neces-
     sary.  The procedure Tcl_InvalidateStringRep is used to mark
     an  object's  string  representation invalid and to free any
     storage associated with the old string representation.

     Objects usually remain one type over their life,  but  occa-
     sionally  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 Tcl_AppendToObj, and
     then call Tcl_ListObjIndex to extract a  list  element  from
     the  object.   The same object holding the same string value
     can have several different internal representations at  dif-
     ferent times.  Extension writers can also force an object to
     be  converted  from  one   type   to   another   using   the
     Tcl_ConvertToType  procedure.   Only programmers that create
     new object types need to be  concerned  about  how  this  is
     done.   A  procedure  defined  as  part of the object type's
     implementation creates a new internal representation for  an
     object  and  changes  its  typePtr.   See  the  man page for
     Tcl_RegisterObjType to see how to create a new object type.

Tcl                     Last change: 8.5                        4

Tcl_Obj(3)           Tcl Library Procedures            Tcl_Obj(3)


     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  Tcl_GetIntFromObj.   This  procedure checks whether
     the object is already an integer object.  Since it  is  not,
     it   converts   the   object   by   setting   the   object's
     internalRep.longValue member to the integer 123 and  setting
     the  object's  typePtr  to  point to the integer Tcl_ObjType
     structure.  Both representations are now valid.  incr incre-
     ments  the  object'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 object  is  needed  and  is
     recomputed.   The  string representation is now 124 and both
     representations are again valid.


     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
     Tcl_NewObj or Tcl_NewStringObj has refCount  0.   The  macro
     Tcl_IncrRefCount  increments  the reference count when a new
     reference   to   the   object   is   created.    The   macro
     Tcl_DecrRefCount decrements the count when a reference is no
     longer needed and, if the object's reference count drops  to
     zero, frees its storage.  An object shared by different code
     or data structures has refCount greater than 1.   Increment-
     ing  an object'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
     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 Tcl_IncrRefCount to increment the  refer-
     ence  count of each argument since there is now a new refer-
     ence to it from the formal parameter.  When the called  pro-
     cedure  returns,  the  interpreter calls Tcl_DecrRefCount to
     decrement each argument's reference count.  When an object's
     reference   count   drops   less  than  or  equal  to  zero,

Tcl                     Last change: 8.5                        5

Tcl_Obj(3)           Tcl Library Procedures            Tcl_Obj(3)

     Tcl_DecrRefCount reclaims its storage.   Most  command  pro-
     cedures do not have to be concerned about reference counting
     since they use an object's  value  immediately  and  do  not
     retain  a pointer to the object after they return.  However,
     if they do retain a pointer to an object in  a  data  struc-
     ture,  they must be careful to increment its reference count
     since the retained pointer is a new reference.

     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 Tcl_IsShared.  If
     the object is shared they must  copy  the  object  by  using
     Tcl_DuplicateObj; this returns a new duplicate of the origi-
     nal object that has  refCount  0.   If  the  object  is  not
     shared,  the  command  procedure  "owns"  the object and can
     safely modify it directly.  For example, the following  code
     appears  in  the  command procedure that implements linsert.
     This procedure modifies the list  object  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 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
     accidentally changing values in other data structures.


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


     internal representation,  object,  object  creation,  object
     type,   reference   counting,  string  representation,  type

Tcl                     Last change: 8.5                        6

Man(1) output converted with man2html