ctcl

Returns the address of a pointer with the help of Tcl API


I'm trying to return the address of a pointer with the help of Tcl API.
Below my simple function :

int simpleTest (Tcl_Interp* interp) {
    
    Context ctx;
    
    // init context
    Init(&ctx);
    // printf("%p\n", &ctx);
    
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("%p", &ctx));

    return TCL_OK;
}

But I have this message :

Unable to format "%p" with supplied arguments

I believe the format %p is not supported by the Tcl API.

How to do it ?


Solution

  • Depending on what you want to achieve, and how portable your implementation should be, you have at least two options:

    a) Cast to an integer type (ideally: uintptr_t) and use the format specifier %#llx. (as suggested by @Tom)

    Tcl_SetObjResult(interp, Tcl_ObjPrintf("%#llx", (uintptr_t)(void*)&ctx));
    

    b) Use sprintf with %p to fill a buffer, and pass that to the Tcl tier (using the %s specifier):

    char hexstr[24];
    sprintf(hexstr,"%p", (void*)&ctx);
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s", hexstr));
    

    I tend to have slight preference for b) because iff the objective is to present the result of %p, and given that %p is defined as "implementation-specific", you might not get the implementation-specific result at the Tcl level when using a).

    Update

    As Donal suggests, using Tcl_NewStringObj:

    char hexstr[24];
    sprintf(hexstr,"%p", (void*)&ctx);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(hexstr, -1));