Tcl Source Code

View Ticket
Login
Ticket UUID: 5edbc4a9f40bd2cfce24e291fc57dea51b7f1a50
Title: It's not possible to manipulate complex data structures inside procs
Type: Bug Version: 8.6
Submitter: anonymous Created on: 2015-09-04 03:44:01
Subsystem: 10. Objects Assigned To: nobody
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2015-09-04 10:38:11
Resolution: Invalid Closed By: ferrieux
    Closed on: 2015-09-04 10:38:11
Description:
In the next code, it's not possible to make manipulations in place, because the reference count is greater than 1. Another possibility is that ::tcl::unsupported::representation lies, and shows the pointer of another object.

I am getting this output:
   value is a pure string with a refcount of 4, object pointer at 0x8528378, string representation "data"
   value is a pure string with a refcount of 5, object pointer at 0x8528378, string representation "data"

This is the code:


proc test {} {
    set variable_name data
    puts [::tcl::unsupported::representation $variable_name]
}

test

namespace eval A { 
    variable var_A data
    puts [::tcl::unsupported::representation $var_A]
    
}
User Comments: ferrieux added on 2015-09-04 10:38:11:
Extra references hide in some unconspicuous places:

   - on the stack when you pass the value as argument
   - on literals
   - on hidden stack levels in case of [interp alias]
   - etc.

In your case, the one that's striking is the literal. Use [expr rand()] to generate a value that will not be stored as a literal.
Then of course the var itself holds a reference. To nuke that one too, use the K-free-K idiom $x[unset x].

Wrapping up:

% proc f {} {set x [expr rand()];puts [tcl::unsupported::representation $x[unset x]]}
% f
value is a double with a refcount of 1, object pointer at 0x8fe4ec0, internal representation 0x1cfea9a0:0x3fef54d0, no string representation
% namespace eval B {
variable var_B [expr rand()]
puts [tcl::unsupported::representation $var_B[unset var_B]]
}
value is a double with a refcount of 1, object pointer at 0x86e9910, internal representation 0xab242eb7:0x3fc2175b, no string representation

sebres added on 2015-09-04 08:24:08:
> it's not possible to make manipulations in place
What did you mean here under manipulations?

That is expected in tcl, that some "static" code objects has a refCount greater as 1, despite you see this object only once, because of interp/namespace literals, code compiling etc. 
Guaranteed refCount = 1 you're going to get, if it will be created and returned to interpreter inside any command, and will be used nowhere otherwise. 

Example:
proc test {} {
    puts [::tcl::unsupported::representation [linsert {} end 1 2 3]]
    puts [::tcl::unsupported::representation [string tolower DATA]]
}

Furthermore you can always create a duplicate with refCount = 1, using function Tcl_DuplicateObj.

Manipulation of object with refCount > 1 is allowed also, for example change to your own Tcl_ObjType (internal representation), but only if it string representation will be not changed or can be always regenerated to the same within your own Tcl_ObjType.

An example for such "complex data structures" are objects contains file/channel/database "handles" etc.

So long it's not clear as a bug, I will close this issue as invalid. Please provide more info if expected.