12

I am trying to understand this code which is from Tcl documentation

typedef int Tcl_DriverOutputProc(
        ClientData instanceData,
        const char *buf,
        int toWrite,
        int *errorCodePtr);

As I know the purpose of typedef is to assign alternative names to existing types, so why is needed to typedef int to function? How this can be used?

Ashot
  • 10,807
  • 14
  • 66
  • 117

3 Answers3

17

I know the purpose of typedef is to assign alternative names to existing types

Exactly. Functions have types, and this assigns the name Tcl_DriverOutputProc to this function type. The function type itself is written like a function with the name missing:

int(ClientData, const char *, int, int *)

and, as with a function declaration, you can include names for the parameters, or leave them out, as you choose.

How this can be used?

You can use pointers to functions in order to specify behaviour at run-time; for example:

typedef void function();
void hello()   {printf("Hello\n");}
void goodbye() {printf("Goodbye\n");}

int main() {
    function * pf = hello;
    pf(); // prints "Hello"
    pf = goodbye;
    pg(); // prints "Goodbye"
}

In this case, it allows you to write a function to handle some aspect of TCL output, and tell TCL to use that function.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Wow, didn't know you could make a typedef for an actual function type (in contrast to the common pointer-to-function typedef) in *C*. But I guess the only possible use case in *C* is indeed to create pointer variables (and thus the usual way is to typedef the pointer type in the first place). But still nice to know. – Christian Rau Apr 17 '13 at 11:58
  • 2
    @ChristianRau: You can also use a function typedef to declare a function, although you still need the normal function-declaration syntax when you define it; and in C++ function types are often used as template arguments (e.g. `std::function`). – Mike Seymour Apr 17 '13 at 12:01
  • Yeah, in the end *C++* makes much more use of *types* at all, be it overloading, templates, ... And I thought this *function-type* syntax was a novum of *C++11*, introduced with things like `std::result_of` and `std::function` in mind. Still some things to learn about good old *C* today ;) – Christian Rau Apr 17 '13 at 12:08
  • Internally, Tcl uses function typedefs for both purposes: providing plug-points in “class description structs” (if it was written in C++, it'd use classes, and there are places where it doesn't have an intervening struct because that would just have one member) and enforcing the restriction that functions that will be used in those structs have the correct declaration. Given the size of the Tcl codebase, being careful like this makes a lot of sense (and gives the best error messages when one messes up). – Donal Fellows Apr 18 '13 at 04:45
  • @MikeSeymour I suppose `pg();` should be `pf();`. However being a very old answer I wont do the edit... maybe I missed something. – Support Ukraine Dec 31 '22 at 08:46
3

typedef can also be used to declare a function say " function_name " and this " function_name " can be used to declare another function of with similar type and parameters.

typedef function_name( int, int);

function_name function1;
function_name *function2;

Here, In your case the typedef statement is used for the declaring " Tcl_DriverOutputProc " function. And " Tcl_DriverOutputProc " is used in " struct Tcl_ChannelType " to declare " *outputProc " .

" struct Tcl_ChannelType " is at the last of the Tcl documentation .

typedef struct Tcl_ChannelType {
    const char *typeName;
     Tcl_ChannelTypeVersion version;
    Tcl_  DriverCloseProc *closeProc;
    Tcl_DriverInputProc *inputProc;
    Tcl_DriverOutputProc *outputProc;   // <-- DriverOutputproc is used here.
    Tcl_DriverSeekProc *seekProc;
    Tcl_DriverSetOptionProc *setOptionProc;
    Tcl_DriverGetOptionProc *getOptionProc;
    Tcl_DriverWatchProc *watchProc;
    Tcl_DriverGetHandleProc *getHandleProc;
    Tcl_DriverClose2Proc *close2Proc;
    Tcl_DriverBlockModeProc *blockModeProc;
    Tcl_DriverFlushProc *flushProc;
    Tcl_DriverHandlerProc *handlerProc;
    Tcl_DriverTruncateProc *truncateProc;
}Tcl_ChannelType;
Biraj Bora
  • 888
  • 2
  • 12
  • 25
0

The syntax of typedefs for function types is wierd -- the type name that you're creating appears in the middle. As Mike Seymour already said, this assigns the name Tcl_DriverOutputProc to the function type int(ClientData, const char *, int, int *).

Ken Bloom
  • 57,498
  • 14
  • 111
  • 168