JoselitoS
JoselitoS

Reputation: 31

What is the correct writing of Tcl_cmdDeleteProc?

I am learning how to extend TCL with C++ and when I came to create new commands with the tcl.h library i found following example, it implements two new commands "Hola" and "Media". The first just print Hola Mundo (spanish for Hello Word) on the screen the second calculate the average of a set of numbers:

#include <stdio.h> 
#include <tcl.h> 
#include <tk.h>

/* Functions prototypes: */

int Tcl_AppInit(Tcl_Interp *interprete);

int hola (ClientData clientdata,Tcl_Interp *interprete,int argc,char *argv[]); 
int media (ClientData clientdata,Tcl_Interp *interprete,int argc,char *argv[]);


void main (int argc,char *argv[]) 
{ 
Tk_Main(argc,argv,Tcl_AppInit); 
} 

/* Tk_Main creates interprete before calling  Tcl_AppInit and then passing it as parameter */ 

int Tcl_AppInit(Tcl_Interp *interprete) 
{ 

/*Intialazing Tcl:*/ 

if(Tcl_Init(interprete)==TCL_ERROR) 
{ 
fprintf(stderr,"Error en la inicialización de Tcl.\n"); 
return TCL_ERROR; 
} 

/*Initialaizing Tk: */ 
if(Tk_Init(interprete)==TCL_ERROR) 
{ 
fprintf(stderr,"Error en la inicialización de Tk.\n"); 
return TCL_ERROR; 
}

/* New commands definitions: */ 
Tcl_CreateCommand(interprete,"hola",hola,(ClientData)NULL, 
(Tcl_CmdDeleteProc *)NULL); 
Tcl_CreateCommand(interprete,"media",media,(ClientData)NULL, 
(Tcl_CmdDeleteProc *)NULL); 

return TCL_OK; 
} 

/* command implementation */ 
int hola (ClientData clientdata,Tcl_Interp *interprete,int argc,char *argv[]) 
{ 
printf("\n\n¡Hola Mundo!!!\n\n"); 
return TCL_OK; 
} 
int media (ClientData clientdata,Tcl_Interp *interprete,int argc,char *argv[]) 
{ 
int elementos; 
double numero; 
double suma; 
int i; 
char **valores; 
char resultado[20];

/* Take data list in argv[1] and use single components: */ 
Tcl_SplitList(interprete,argv[1],&elementos,&valores); 
for(suma=0,i=0;i<elementos;i++) 
{ 
if(Tcl_GetDouble(interprete,valores[i],&numero)==TCL_ERROR) 
{ 
Tcl_SetResult(interprete,"Error en los parámetros",TCL_STATIC); 
return TCL_ERROR; 
} 
suma+=numero; 
} 
sprintf(resultado,"%f",suma/elementos); 
Tcl_SetResult(interprete,resultado,TCL_VOLATILE); 
return TCL_OK; 
}

The example seems old for me and from an Borland programer (because of the Void Main). When I tried to compile I got two errors on the new command definitions.

  /* New commands definitions: */ 
Tcl_CreateCommand(interprete,"hola",hola,(ClientData)NULL, 
(Tcl_CmdDeleteProc *)NULL); 
Tcl_CreateCommand(interprete,"media",media,(ClientData)NULL, 
(Tcl_CmdDeleteProc *)NULL); 

I get errors on

(ClientData)NULL

and

(Tcl_CmdDeleteProc *)NULL

After reading the Tcl manual I managed to change:

(ClientData)NULL to ClientData(NULL)

and it solved the first error but the second keep on giving error.

The errors:

For

(Tcl_CmdDeleteProc *)NULL --> not valid type conversion -fpermissive

For

Tcl_CmdDeleteProc *(NULL) --> needed primary expresion before token

For just typing NULL

NULL --> not valid type conversion

My question are: Am i writting it wrong? do I have to define Tcl_CmdDeleteProc s type?

I am compiling without flags, just "g++ -Wall name.cc -o name.o"

Upvotes: 1

Views: 164

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137627

First off, Tcl_CmdDeleteProc is a typedef for a function type. Function types have somewhat restrictive rules about what you can do with them.

The code:

Tcl_CmdDeleteProc *(NULL)

is completely wrong, as it is just a parse error. The code:

(Tcl_CmdDeleteProc *)NULL

is correct, but it's a C-style explicit cast and your compiler is set to complain about those without the -fpermissive flag set. For C++, you probably want a static cast:

static_cast<Tcl_CmdDeleteProc *>(nullptr)

(If you're using an older C++, use NULL instead of nullptr.)

Upvotes: 1

Related Questions