From: chris.m.thomasson.1@gmail.com   
      
   On 1/3/2026 4:55 AM, David Brown wrote:   
   > On 02/01/2026 23:18, Chris M. Thomasson wrote:   
   >> On 1/2/2026 1:52 PM, Kaz Kylheku wrote:   
   >>> On 2026-01-02, Michael Sanders wrote:   
   >>>> On Fri, 2 Jan 2026 17:48:16 -0000 (UTC), Kaz Kylheku wrote:   
   >>>>   
   >>>>> On 2026-01-02, Michael Sanders wrote:   
   >>>>>> B: because every function must have a return type   
   >>>>>> *including function pointers*?   
   >>>>>   
   >>>>> What it is you think type is, in the context of C?   
   >>>>>   
   >>>>> Does type survive into run-time?   
   >>>>>   
   >>>>> If a function pointer is missing type information about return   
   >>>>> type, and   
   >>>>> that function pointer is needed for expressing a function call, where   
   >>>>> does the compiler get the type from?   
   >>>>   
   >>>> Its void that's throwing me Kaz. I'm not sure what to think when   
   >>>> it comes to void pointers.   
   >>>   
   >>> Because you teleported here from 1985.   
   >>   
   >> [...]   
   >>   
   >> One note, void* cannot hold a function pointer without getting   
   >> undefined or implementation-defined behavior.   
   >>   
   >   
   > Kaz mentioned several types that "void *" is a generic /object/ pointer.   
      
   Oh, I missed that. Sorry everybody.   
      
      
   > Functions are not objects - pointers to functions are completely   
   > different from pointers to objects. You can't mix them without "I know   
   > what I am doing" explicit casts, with non-portable behaviour and a   
   > serious risk of UB.   
      
   Indeed.   
      
      
   >> typedef void (*generic_func_ptr)(void)   
   >   
   > There is no generic function pointer type equivalent to "void *" - you   
   > are always going to need casts when converting between different pointer   
   > types. And you /really/ need to make sure you convert to exactly the   
   > correct type before calling the pointed-to function. But the definition   
   > you gave here is commonly used when people want to have generic function   
   > pointers.   
   >   
      
   Agreed. Fwiw, here is some of my old code exploring some related things:   
      
      
   /* Interfaces   
   ____________________________________________________________________*/   
   #include    
      
      
   struct object_prv_vtable {   
    int (*fp_destroy) (void* const);   
   };   
      
      
   struct device_prv_vtable {   
    int (*fp_read) (void* const, void*, size_t);   
    int (*fp_write) (void* const, void const*, size_t);   
   };   
      
      
   struct device_vtable {   
    struct object_prv_vtable const object;   
    struct device_prv_vtable const device;   
   };   
      
      
   struct device {   
    struct device_vtable const* vtable;   
   };   
      
      
   #define object_destroy(mp_self) ( \   
    (mp_self)->vtable->object.fp_destroy((mp_self)) \   
   )   
      
      
   #define device_read(mp_self, mp_buf, mp_size) ( \   
    (mp_self)->vtable->device.fp_read((mp_self), (mp_buf), (mp_size)) \   
   )   
      
      
   #define device_write(mp_self, mp_buf, mp_size) ( \   
    (mp_self)->vtable->device.fp_write((mp_self), (mp_buf), (mp_size)) \   
   )   
      
      
      
      
      
      
   /* Sample Header (usb_drive.h)   
   ____________________________________________________________________*/   
   #if ! defined(USB_HEADER_H)   
   #define USB_HEADER_H   
      
      
   extern int usb_drive_create(struct device** const);   
      
      
   #endif   
      
      
      
      
      
      
      
   /* Sample Impl (usb_drive.c)   
   ____________________________________________________________________*/   
   /* #include "usb_drive.c" */   
   #include    
   #include    
      
      
   struct usb_drive {   
    struct device device;   
    /* whatever */   
   };   
      
      
   static int usb_drive_object_destroy(void* const);   
   static int usb_drive_device_read(void* const, void*, size_t);   
   static int usb_drive_device_write(void* const, void const*, size_t);   
      
      
   static struct device_vtable const g_table = {   
    { /* object */   
    usb_drive_object_destroy   
    },   
      
    { /* device */   
    usb_drive_device_read,   
    usb_drive_device_write   
    }   
   };   
      
      
   int usb_drive_create(   
    struct device** const pself   
   ) {   
    struct usb_drive* const self = malloc(sizeof(*self));   
    if (self) {   
    self->device.vtable = &g_table;   
    *pself = &self->device;   
    return 0;   
    }   
    return -1;   
   }   
      
      
   int usb_drive_object_destroy(   
    void* const self_   
   ) {   
    struct usb_drive* const self = self_;   
    printf("usb_drive_object_destroy(%p)\n", (void*)self);   
    free(self_);   
    return 0;   
   }   
      
      
   int usb_drive_device_read(   
    void* const self_,   
    void* buf,   
    size_t size   
   ) {   
    struct usb_drive* const self = self_;   
    printf("usb_drive_device_read(%p, %p, %lu)\n",   
    (void*)self, buf, (unsigned long)size);   
    return 0;   
   }   
      
      
   int usb_drive_device_write(   
    void* const self_,   
    void const* buf,   
    size_t size   
   ) {   
    struct usb_drive* const self = self_;   
    printf("usb_drive_device_write(%p, %p, %lu)\n",   
    (void*)self, buf, (unsigned long)size);   
    return 0;   
   }   
      
      
      
      
      
      
      
   /* Sample Application   
   ____________________________________________________________________*/   
   void read_write(   
    struct device* const self   
   ) {   
    char buf[100];   
      
    device_read(self, buf, 50);   
      
    device_write(self, buf, 5);   
   }   
      
      
   int main(void) {   
    struct device* a_device;   
      
    if (! usb_drive_create(&a_device)) {   
    read_write(a_device);   
      
    object_destroy(a_device);   
    }   
      
    return 0;   
   }   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|