home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 242,738 of 243,242   
   Chris M. Thomasson to David Brown   
   Re: function pointer question   
   03 Jan 26 12:04:47   
   
   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)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca