• doc error?

    From saito@[email protected] to comp.lang.tcl on Sun Feb 8 14:05:43 2026
    From Newsgroup: comp.lang.tcl

    I was not expecting this to throw an error. Docs says it should return 0
    or 1. How would you do this check?

    % package req Thread
    2.8.5

    % thread::exists ""
    invalid thread handle ""

    % thread::exists abc
    invalid thread handle "abc"


    But then this works:

    % thread::exists tid1
    0

    Weird. It looks like the check expects the argument to start with "tid"
    and a number.

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Harald Oehlmann@[email protected] to comp.lang.tcl on Sun Feb 8 20:26:45 2026
    From Newsgroup: comp.lang.tcl

    Am 08.02.2026 um 20:05 schrieb saito:
    I was not expecting this to throw an error. Docs says it should return 0
    or 1. How would you do this check?

    % package req Thread
    2.8.5

    % thread::exists ""
    invalid thread handle ""

    % thread::exists abc
    invalid thread handle "abc"


    But then this works:

    % thread::exists tid1
    0

    Weird. It looks like the check expects the argument to start with "tid"
    and a number.


    Yes, please file a bug report:

    https://core.tcl-lang.org/thread/ticket

    Thanks,
    Harald
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From undroidwish@[email protected] to comp.lang.tcl on Sun Feb 8 22:40:39 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/26 20:26, Harald Oehlmann wrote:
    Am 08.02.2026 um 20:05 schrieb saito:
    I was not expecting this to throw an error. Docs says it should return
    0 or 1. How would you do this check?

    % package req Thread
    2.8.5

    % thread::exists ""
    invalid thread handle ""

    % thread::exists abc
    invalid thread handle "abc"


    But then this works:

    % thread::exists tid1
    0

    Weird. It looks like the check expects the argument to start with
    "tid" and a number.


    Yes, please file a bug report:

    https://core.tcl-lang.org/thread/ticket

    Honestly am I puzzled. Why should this non-problem deserve a bug report?
    The fact to construct a thread identifier out of blue strings seems to
    me to be a somehow somewhat malicious act. So how can there be any
    expectations on arbitrary generated thread identifiers being error'd?
    Or answered as non existing?

    In other words: the errors thrown on impossible thread identifiers is
    the correct answer for the query on thread existence.

    Finally, IMO please do not create a ticket.

    BR,
    Christian
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From undroidwish@[email protected] to comp.lang.tcl on Sun Feb 8 22:49:17 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/26 22:40, undroidwish wrote:

    Finally, IMO please do not create a ticket.

    ... and simply live with the fact that some strings are
    impossible thread identifiers, and some not, but don't
    represent existing threads.

    BR,
    Christian
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Robert Heller@[email protected] to comp.lang.tcl on Sun Feb 8 21:53:43 2026
    From Newsgroup: comp.lang.tcl

    At Sun, 8 Feb 2026 22:40:39 +0100 undroidwish <[email protected]> wrote:

    On 2/8/26 20:26, Harald Oehlmann wrote:
    Am 08.02.2026 um 20:05 schrieb saito:
    I was not expecting this to throw an error. Docs says it should return
    0 or 1. How would you do this check?

    % package req Thread
    2.8.5

    % thread::exists ""
    invalid thread handle ""

    % thread::exists abc
    invalid thread handle "abc"


    But then this works:

    % thread::exists tid1
    0

    Weird. It looks like the check expects the argument to start with
    "tid" and a number.


    Yes, please file a bug report:

    https://core.tcl-lang.org/thread/ticket

    Honestly am I puzzled. Why should this non-problem deserve a bug report?
    The fact to construct a thread identifier out of blue strings seems to
    me to be a somehow somewhat malicious act. So how can there be any expectations on arbitrary generated thread identifiers being error'd?
    Or answered as non existing?

    In other words: the errors thrown on impossible thread identifiers is
    the correct answer for the query on thread existence.

    Finally, IMO please do not create a ticket.
    The OP is NOT expecting thread::exists to behave any differently than it does, just that thread::exists behavior be completely and accurately documented. Appearently, the documentation is mute as to what thread::exists does when given a string that is not a proper thread id, with the (erronious) *presumption* that it would return 0 (which is in fact NOT what it does). This is a *documentation* bug. And the suggested bug report relates to the *documentation*, not the actual code.

    BR,
    Christian


    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@[email protected] to comp.lang.tcl on Sun Feb 8 17:32:48 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/2026 4:40 PM, undroidwish wrote:
    On 2/8/26 20:26, Harald Oehlmann wrote:
    Am 08.02.2026 um 20:05 schrieb saito:


    Weird. It looks like the check expects the argument to start with
    "tid" and a number.


    Yes, please file a bug report:

    https://core.tcl-lang.org/thread/ticket

    Honestly am I puzzled. Why should this non-problem deserve a bug report?

    Well, it wasn't my suggestion to file a bug report.

    There is a discrepancy and a potentially dangerous, unfounded assumption behind that simple command. Consider the intention behind using thread::exists. It is plainly so to avoid mistakes or core dumps. But
    here, it does the exact opposite.

    Consider a similar construct in prupose, "string is integer": before
    jumping to performing some arithmetic, you may want to use it for
    protection. But if it blows up, then how can you ever fix it or do
    anything with it?


    The fact to construct a thread identifier out of blue strings seems to
    me to be a somehow somewhat malicious act.
    It happens when you get it from external source or the network fails or
    comms gets corrupted or whatever. I am curious why anyone should care
    about what an identifier handle or string should look like. It is just a
    bunch of mumbo jumbo, apart from the fact that it is unique and provides access to a certain thing.

    If it is important, then it should be documented. You think it is "tid" followed by numbers? Not so. Why is "tidabc" ok here but not "tidxyz"?

    % thread::exists tidabc
    0

    % thread::exists tidxyz
    invalid thread handle "tidxyz"


    Continuing with the string example above, see how the string integer
    check does what it says and protects you from blindly going forward with
    what you have.

    % string is integer abc
    0

    % string is integer "123 . 456"
    0

    % string is integer [image create photo]
    0

    % string is integer {^@<83>BÈ&½<86>}
    0

    thread::exists exists for the same purpose but it does not do the same
    thing.










    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@[email protected] to comp.lang.tcl on Sun Feb 8 17:40:30 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/2026 4:53 PM, Robert Heller wrote:
    At Sun, 8 Feb 2026 22:40:39 +0100 undroidwish <[email protected]> wrote:

    Finally, IMO please do not create a ticket.

    The OP is NOT expecting thread::exists to behave any differently than it does,
    just that thread::exists behavior be completely and accurately documented. Appearently, the documentation is mute as to what thread::exists does when given a string that is not a proper thread id, with the (erronious) *presumption* that it would return 0 (which is in fact NOT what it does). This
    is a *documentation* bug. And the suggested bug report relates to the *documentation*, not the actual code.


    It started like this but it looks like thread::exists does not
    necessarily function 100%. Documentation can fix this easily by
    requiring a certain format for the id's. But then you will be left to
    add extra code on your own which I think is the purpose of thread::exists.


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@[email protected] to comp.lang.tcl on Sun Feb 8 16:01:33 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/2026 2:32 PM, saito wrote:


    If it is important, then it should be documented. You think it is "tid" followed by numbers? Not so. Why is "tidabc" ok here but not "tidxyz"?

    % thread::exists tidabc
    0

    % thread::exists tidxyz
    invalid thread handle "tidxyz"



    The code that checks is,

    static int
    ThreadGetId(interp, handleObj, thrIdPtr)
    Tcl_Interp *interp;
    Tcl_Obj *handleObj;
    Tcl_ThreadId *thrIdPtr;
    {
    const char *thrHandle = Tcl_GetString(handleObj);

    if (sscanf(thrHandle, THREAD_HNDLPREFIX"%p", thrIdPtr) == 1) {
    return TCL_OK;
    }

    Tcl_AppendResult(interp, "invalid thread handle \"",
    thrHandle, "\"", NULL);
    return TCL_ERROR;
    }


    So, it depends on how sscanf treats %p, and in most cases this has to be a valid pointer, usually a hex number, and abc is valid hex, while xyz is not.

    -e

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Harald Oehlmann@[email protected] to comp.lang.tcl on Mon Feb 9 08:22:21 2026
    From Newsgroup: comp.lang.tcl

    Hi Chrstian, all,

    I am very happy about the discussion.

    Ihe intention to file a bug report is to have this discussion in a
    ticket and not here. So the discussion may be found later.

    About "error or not".
    Most "exists" functions in TCL don't throw errors on invalid arguments.
    For example,
    dict exits {} a b
    has thrown an error in an earlier version of TCL.
    This was changed to not throw an error.

    Thanks for all,
    Harald
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@[email protected] to comp.lang.tcl on Mon Feb 9 11:44:01 2026
    From Newsgroup: comp.lang.tcl

    On 2/9/2026 2:22 AM, Harald Oehlmann wrote:
    Hi Chrstian, all,

    I am very happy about the discussion.

    Ihe intention to file a bug report is to have this discussion in a
    ticket and not here. So the discussion may be found later.


    That sounds good. I will try to file the report sometime this week when
    I get the chance.


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Christian Gollwitzer@[email protected] to comp.lang.tcl on Mon Feb 9 20:44:13 2026
    From Newsgroup: comp.lang.tcl

    Am 09.02.26 um 08:22 schrieb Harald Oehlmann:
    Hi Chrstian, all,

    I am very happy about the discussion.

    Ihe intention to file a bug report is to have this discussion in a
    ticket and not here. So the discussion may be found later.

    About "error or not".
    Most "exists" functions in TCL don't throw errors on invalid arguments.
    For example,
    dict exits {} a b
    has thrown an error in an earlier version of TCL.
    This was changed to not throw an error.

    I tend to agree with the other Christian. If Tcl had types, then the
    argument to thread::exists would be a Thread identifier and there would
    not be a way to pass some artbitrary object to it. The purpose of this function is to see, if a thread identifier - something you got back from thread::create - corresponds to a running thread. If you pass it
    something which is not a thread identifier, than there is a bug in your program.

    Christian
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Robert Heller@[email protected] to comp.lang.tcl on Mon Feb 9 20:16:56 2026
    From Newsgroup: comp.lang.tcl

    At Mon, 9 Feb 2026 20:44:13 +0100 Christian Gollwitzer <[email protected]> wrote:

    Am 09.02.26 um 08:22 schrieb Harald Oehlmann:
    Hi Chrstian, all,

    I am very happy about the discussion.

    Ihe intention to file a bug report is to have this discussion in a
    ticket and not here. So the discussion may be found later.

    About "error or not".
    Most "exists" functions in TCL don't throw errors on invalid arguments.
    For example,
    dict exits {} a b
    has thrown an error in an earlier version of TCL.
    This was changed to not throw an error.

    I tend to agree with the other Christian. If Tcl had types, then the
    argument to thread::exists would be a Thread identifier and there would
    not be a way to pass some artbitrary object to it. The purpose of this function is to see, if a thread identifier - something you got back from thread::create - corresponds to a running thread. If you pass it
    something which is not a thread identifier, than there is a bug in your program.
    The problem is that this is NOT documented. The documentation should document this behaviour.

    Christian


    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@[email protected] to comp.lang.tcl on Mon Feb 9 17:47:46 2026
    From Newsgroup: comp.lang.tcl

    On 2/9/2026 2:44 PM, Christian Gollwitzer wrote:
    Am 09.02.26 um 08:22 schrieb Harald Oehlmann:

    If you pass it
    something which is not a thread identifier, than there is a bug in your program.


    In that case, I am afraid we may need a new command to check if
    something is a valid thread identifier, not just a real/active one. I
    get it, internally it makes sense that the id's have a nice logic and
    format to it. I am of the opinion that this detail can remain internal.

    My original question remains: "How would you do this check?" when you
    receive a thread id from an evil user or colleague or simply by mistake?

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Emiliano@[email protected] to comp.lang.tcl on Mon Feb 9 21:02:27 2026
    From Newsgroup: comp.lang.tcl

    On Mon, 9 Feb 2026 20:44:13 +0100
    Christian Gollwitzer <[email protected]> wrote:

    [...]
    I tend to agree with the other Christian. If Tcl had types, then the argument to thread::exists would be a Thread identifier and there would
    not be a way to pass some artbitrary object to it. The purpose of this function is to see, if a thread identifier - something you got back from thread::create - corresponds to a running thread. If you pass it
    something which is not a thread identifier, than there is a bug in your program.

    Well, I agree with Harald here. The semantics of "exists" subcommands is
    to return true if the thing exists, or false otherwise, without considering *why* it doesn't exists; it doesn't, so return 0. There are plenty of
    examples in Tcl (and Tk):

    # namespace foo::bar doesn't exists
    % info exists foo::bar::baz
    0
    % namespace exists foo::bar::baz
    0
    % namespace ensemble exists foo::bar::baz
    0
    # "foo" is not a valid dictionary
    % dict exists foo a
    0
    # "Nosuchwindow" is not a valid window name
    % package require Tk; winfo exists Nosuchwindow
    0

    Having to test if the handle conforms to certain naming convention and
    only then test whether it exists or not is, IMO, a bug. Not to mention
    that values such as "tidabcXYZ AND SOME NONSENSE", which is an invalid
    thread identifier, will pass the test.

    Regards
    --
    Emiliano <[email protected]>
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From undroidwish@[email protected] to comp.lang.tcl on Tue Feb 10 23:06:14 2026
    From Newsgroup: comp.lang.tcl

    On 2/9/26 23:47, saito wrote:

    ...
    My original question remains: "How would you do this check?" when you receive a thread id from an evil user or colleague or simply by mistake?

    Due to the nature of threads their sheer existence is bound to their
    containing process. Are there real use cases where a thread identifier
    is given to the process' outer world? Yes, I know, some POSIX IPC means
    can be process shared, but those are mutexen and the like, threads not
    so much. Ahem, well there might be the need to kill a thread, but then
    again, the Tcl thread identifier doesn't make sense either, since the
    native thread id is needed which most likely does not equal the Tcl
    thread identifier.

    BR,
    Christian

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Christian Gollwitzer@[email protected] to comp.lang.tcl on Wed Feb 11 07:35:55 2026
    From Newsgroup: comp.lang.tcl

    Am 10.02.26 um 23:06 schrieb undroidwish:
    On 2/9/26 23:47, saito wrote:

    ...
    My original question remains: "How would you do this check?" when you
    receive a thread id from an evil user or colleague or simply by mistake?

    Due to the nature of threads their sheer existence is bound to their containing process. Are there real use cases where a thread identifier
    is given to the process' outer world?

    Exactly that was my reasoning. If you pass anything as a thread
    identifier to any of the thread:: functions, and it is not what you got
    from thread::create, then you have a bug in your program. The thread ID
    is an opaque handle and should be treated like a pointer in C. You don't
    write a pointer to a file and read it back later, your program will
    crash. I could only see the need for a sentinel value, like the empty
    string, so that you can initialize a variable.

    The Other Christian


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Ralf Fassel@[email protected] to comp.lang.tcl on Wed Feb 11 10:36:19 2026
    From Newsgroup: comp.lang.tcl

    * Christian Gollwitzer <[email protected]>
    | Am 10.02.26 um 23:06 schrieb undroidwish:
    | > On 2/9/26 23:47, saito wrote:
    | >
    | >> ...
    | >> My original question remains: "How would you do this check?" when
    | >> you receive a thread id from an evil user or colleague or simply by
    | >> mistake?
    | > Due to the nature of threads their sheer existence is bound to their
    | > containing process. Are there real use cases where a thread identifier
    | > is given to the process' outer world?

    | Exactly that was my reasoning. If you pass anything as a thread
    | identifier to any of the thread:: functions, and it is not what you
    | got from thread::create, then you have a bug in your program.

    It should be documented, I think that much is undisputed.

    If anyone needs a threadid-safe version (pun intended :-) of thread::exists,

    proc thread_exists_safe {id} {
    return [expr {![catch {thread::exists $id} exists] && $exists}]
    }

    is quickly coded (even without asking ChatGPT)...

    R'
    --- Synchronet 3.21b-Linux NewsLink 1.2