TIP 757: Functions for Generating a Result String

Login
Author:         Donal Fellows <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        04-Jul-2026
Tcl-Version:    9.2
Tcl-Branch:     tip-757
Forum:          9e45d2e891
Keywords:       Tcl, result, printf

Abstract

This TIP proposes helper functions that make writing to the Tcl result easier, especially when generating error messages.

Background

Back in Tcl 7.6, you could generate messages in Tcl's result like this (providing they were fairly short):

sprintf(interp->result, "bad value %s: should be foo", argv[1]);

This ease has been lost along the way somewhat during the Tcl 8 series. The above would be currently best as:

Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad value %s: should be foo", Tcl_GetString(objv[1])));

This is less than ideal, especially in that it is visually heavy. We ought to do better.

Specification

I propose adding three functions, Tcl_PrintfResult(), Tcl_AppendPrintfResult(), and Tcl_AppendPrintfToErrorInfo(), to Tcl's public API.

Tcl_PrintfResult

This function shall take two mandatory arguments, the handle to the Tcl interpreter and the format string (ideally a compile-time literal, just as with Tcl_ObjPrintf), plus as many other arguments as the format requires. It shall have no result.

void Tcl_PrintfResult(Tcl_Interp *interp, const char *format, ...);

The aim is that calling:

Tcl_PrintfResult(interp, "formatStr", extraArgs...);

should be understood at a practical level to be equivalent to calling:

Tcl_SetObjResult(interp, Tcl_ObjPrintf("formatStr", extraArgs...));

The implementation guarantees that the interpreter result will only be altered after all arguments are used.

Tcl_AppendPrintfResult

This function shall be similar to Tcl_PrintfResult (including in arguments provided and result returned), but will append the formatted string to the result value rather than replacing it.

The implementation does not guarantee that the result will only be modified after all arguments are used (which is to say that using, e.g., Tcl_GetString(Tcl_GetObjResult(interp)), to provide an argument to Tcl_AppendPrintfResult shall be a hazard unless a separate reference to the result is known to be retained elsewhere).

Tcl_AppendPrintfToErrorInfo

This function shall be similar to Tcl_AppendPrintfResult (including in arguments provided and result returned), but will append the formatted string to the error info (with the same semantics of initialisation as Tcl_AddToErrorInfo).

The implementation does not guarantee that the error info will only be modified after all arguments are used. (This is rarely a problem in practice.)

Future Work

A format specifier for Tcl_Obj* fields

We should enhance the format string processing of AppendPrintfToObjVA (hence Tcl_ObjPrintf, Tcl_PrintfResult, etc.) to include a conversion that applies Tcl_GetString to a Tcl_Obj reference to obtain a string. However, this should only be done if we can guarantee that the format command can't provide such a conversion; it's totally unsafe to do this without.

Due to the complexity of needing that safety guarantee, this may be omitted from this TIP and reserved for a future one. If it proves practical to implement safely on a short enough timeline, it will be added to this TIP.

It should be noted, however, that doing this also loses the ability for compilers and IDEs to check our format strings while we are building or writing our code. (This is apparently a long-standing issue for other codebases that do these sorts of tricks.)

Implementation

The branch c11-printf-result was an implementation of this, done as a C11 variadic macro and not part of the public API. This TIP is based on that, especially on the experience of using it, but will not use the code from that branch.

Copyright

This document has been placed in the public domain.