Provided by: tcl8.6-doc_8.6.14+dfsg-1build1_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

Tcl                                                    8.5                                         Tcl_Obj(3tcl)