Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #95500 > unrolled thread

Aliasing and subtyping structs

Started byAndreas <nospam@invalid.invalid>
First post2016-11-01 13:15 +0100
Last post2016-12-14 10:14 -0800
Articles 20 on this page of 60 — 16 participants

Back to article view | Back to comp.lang.c


Contents

  Aliasing and subtyping structs Andreas <nospam@invalid.invalid> - 2016-11-01 13:15 +0100
    Re: Aliasing and subtyping structs Andreas <nospam@invalid.invalid> - 2016-11-01 13:34 +0100
      Re: Aliasing and subtyping structs Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-01 15:27 +0000
        Re: Aliasing and subtyping structs Andreas <nospam@invalid.invalid> - 2016-11-02 09:47 +0100
          Re: Aliasing and subtyping structs Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-02 15:47 +0000
            Re: Aliasing and subtyping structs Andreas <nospam@invalid.invalid> - 2016-11-08 00:24 +0100
              Re: Aliasing and subtyping structs supercat@casperkitty.com - 2016-11-07 21:42 -0800
          Re: Aliasing and subtyping structs <william@wilbur.25thandClement.com> - 2016-11-03 18:53 -0700
            Re: Aliasing and subtyping structs supercat@casperkitty.com - 2016-11-04 09:56 -0700
            Re: Aliasing and subtyping structs Andreas <nospam@invalid.invalid> - 2016-11-08 21:53 +0100
    Re: Aliasing and subtyping structs James Kuyper <jameskuyper@verizon.net> - 2016-11-01 11:41 -0400
      Re: Aliasing and subtyping structs Andreas <nospam@invalid.invalid> - 2016-11-02 09:55 +0100
    "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2016-11-21 16:59 +0300
      Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-21 07:32 -0800
      Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "James R. Kuyper" <jameskuyper@verizon.net> - 2016-11-21 11:15 -0500
        Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-21 08:35 -0800
          Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2016-11-22 11:42 +0300
            Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-22 06:50 -0800
              Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-22 16:07 +0000
                Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-22 12:02 -0800
                  Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-22 23:36 +0000
                    Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-22 16:24 -0800
                      Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Richard Damon <Richard@Damon-Family.org> - 2016-11-22 22:21 -0500
                        Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-23 08:31 -0800
                          Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] me <crisdunbar@gmail.com> - 2016-11-23 09:01 -0800
                            Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-23 12:05 -0800
        Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Anton Shepelev <anton.txt@gmail.com> - 2016-11-22 23:23 +0300
          Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "James R. Kuyper" <jameskuyper@verizon.net> - 2016-11-22 16:02 -0500
            Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-22 14:13 -0800
              Re: container_of() macro Noob <root@127.0.0.1> - 2016-11-23 01:10 +0100
                Re: container_of() macro <william@wilbur.25thandClement.com> - 2016-11-22 20:10 -0800
                  Re: container_of() macro "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-11-23 15:10 -0800
                Re: container_of() macro David Brown <david.brown@hesbynett.no> - 2016-11-23 11:31 +0100
                  Re: container_of() macro Anton Shepelev <anton.txt@g{oogle}mail.com> - 2016-11-23 14:07 +0300
                  Re: container_of() macro supercat@casperkitty.com - 2016-11-23 08:41 -0800
            Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Anton Shepelev <anton.txt@gmail.com> - 2016-11-30 00:14 +0300
              Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "James R. Kuyper" <jameskuyper@verizon.net> - 2016-11-29 17:23 -0500
                Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Anton Shepelev <anton.txt@gmail.com> - 2016-12-04 18:48 +0300
                  Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "James R. Kuyper" <jameskuyper@verizon.net> - 2016-12-04 12:17 -0500
                    Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Anton Shepelev <anton.txt@gmail.com> - 2016-12-04 22:15 +0300
                      Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "James R. Kuyper" <jameskuyper@verizon.net> - 2016-12-04 15:06 -0500
                        Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Anton Shepelev <anton.txt@gmail.com> - 2016-12-12 22:31 +0300
      Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-11-23 13:39 -0800
        Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] luser droog <luser.droog@gmail.com> - 2016-11-23 15:10 -0800
          Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-11-23 15:13 -0800
            Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] luser droog <luser.droog@gmail.com> - 2016-11-23 18:29 -0800
            Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2016-11-24 11:41 +0300
            Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Thiago Adams <thiago.adams@gmail.com> - 2016-11-24 03:29 -0800
              Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-11-24 17:37 -0800
                Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-25 09:55 -0800
                Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Thiago Adams <thiago.adams@gmail.com> - 2016-11-25 15:22 -0800
                  Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-11-28 18:18 -0800
                    Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Thiago Adams <thiago.adams@gmail.com> - 2016-11-29 04:48 -0800
                      Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-29 07:28 -0800
                        Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Thiago Adams <thiago.adams@gmail.com> - 2016-11-30 08:26 -0800
                          Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] supercat@casperkitty.com - 2016-11-30 09:13 -0800
                      Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-12 16:44 -0800
                        Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Melzzzzz <mel@zzzzz.com> - 2016-12-13 02:18 +0100
                        Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Thiago Adams <thiago.adams@gmail.com> - 2016-12-14 09:47 -0800
                          Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs] Thiago Adams <thiago.adams@gmail.com> - 2016-12-14 10:14 -0800

Page 3 of 3 — ← Prev page 1 2 [3]


#97995 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-12-04 15:06 -0500
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<f99dce16-6d8d-df02-fcc4-e4a2f8c911ac@verizon.net>
In reply to#97989
On 12/04/2016 02:15 PM, Anton Shepelev wrote:
> Given the code:
>
>    struct a { int x; };
>    struct c { struct a a; ... } c, * cp = & c;
>    struct a * ap = & c.a;
>
> James R. Kuyper to Anton Shepelev:
>
>>> Would this:
>>>
>>>    ap = (struct a *) cp; /* alias to cp */
>>>    ap -> x
>>>
>>> be wrong?
>>
>> No,  because  the  result  of that conversion is a
>> pointer which is defined  as   pointing  at  cp.a.
>> That  is  an object with the declared type "struct
>> a", which is therefore also it's  effective  type.
>> Since  the  effective  type  of the object exactly
>> matches the type of the lvalue that is used to ac-
>> cess it, it is covered by the first item in 6.5p7:
>> "a type compatible with the effective type of  the
>> object".  "Two types have compatible type if their
>> types are the same." (6.2.7p1)
>
> Thanks.  If the first field of a  stucture  has  the
> same type as that of the pointer target then pointer
> conversion works.  Will I violate aliasing if I  re-
> place cp with &c, i.e.:
>
>    cp = &c;
>    ap = (struct a *)&c; /* alias to cp */
>    ap -> x

Why are you worried about the possibility of getting a different answer 
in this case? Since cp == &c, (struct a*)cp and (struct a*)&c have 
precisely the same behavior, and in particular, precisely the same lack 
of aliasing problems.

Unless I've missed some important point (which is not impossible - it's 
happened before), it seems to me that you must be seriously 
misunderstanding something, but your questions have not yet revealed to 
me what that misunderstanding is. If you could explain, in detail, why 
you thought there might be a problem, I might be able to identify what 
it is that you're misunderstanding. Alternatively, that explanation 
might help me identify the "important point" that I've been missing.

[toc] | [prev] | [next] | [standalone]


#99117 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromAnton Shepelev <anton.txt@gmail.com>
Date2016-12-12 22:31 +0300
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<20161212223152.1b570d6da83626125db8ea80@gmail.com>
In reply to#97995
James R. Kuyper to Anton Shepelev:

> > struct a { int x; };
> > struct c { struct a a; ... } c, * cp = & c;
> > struct a * ap = & c.a;
> >
> > Thanks.  If the first field of a  stucture  has  the
> > same type as that of the pointer target then pointer
> > conversion works.  Will I violate aliasing if I  re-
> > place cp with &c, i.e.:
> >
> >    cp = &c;
> >    ap = (struct a *)&c; /* alias to cp */
> >    ap -> x
>
> Why  are you worried about the possibility of get-
> ting a different answer in this case? Since cp  ==
> &c, (struct a*)cp and (struct a*)&c have precisely
> the same behavior, and  in  particular,  precisely
> the same lack of aliasing problems.
>
> Unless  I've missed some important point (which is
> not impossible - it's happened before),  it  seems
> to  me that you must be seriously misunderstanding
> something, but your questions  have  not  yet  re-
> vealed to me what that misunderstanding is. If you
> could explain, in detail, why  you  thought  there
> might  be  a  problem, I might be able to identify
> what it is that you're misunderstanding.  Alterna-
> tively,  that  explanation  might help me identify
> the "important point" that I've been missing.

No, no it is clearly I who lack understanding :-)

I am worried because C does not allow the use of two
pointers  to  the  same  location but with different
target types with the exceptions that  are  known as
the  rules  of  strict  aliasing.  Why can cp and ap
alias in the example above?  Is it  because  of  the
following item in 6.5.7:

   An  object  shall  have its stored value accessed
   only by an lvalue expression that has one of  the
   following types:
   [...]

     -- an aggregate or union type that includes one
        of the aforementioned types among  its  mem-
        bers  (including, recursively, a member of a
        subaggregate or contained union),

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#97361 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2016-11-23 13:39 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<o1528t$uaa$1@dont-email.me>
In reply to#97197
On 11/21/2016 5:59 AM, Anton Shepelev wrote:
> Andreas:
>
>> Hi all,
[...]
> Am I right in thinking  that  "Object-oriented  pro-
> gramming in C":
>
>       http://www.cs.rit.edu/~ats/books/ooc.pdf
>
> is  based entirely on the violation of strict alias-
> ing?

Well, I sort of like the following technique:

http://pastebin.com/f52a443b1

Not even trying to make full OOP, but its fairly nice...

;^)

[toc] | [prev] | [next] | [standalone]


#97365 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

Fromluser droog <luser.droog@gmail.com>
Date2016-11-23 15:10 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<51b9526c-9a0f-4e1b-9b86-ef9eff06b558@googlegroups.com>
In reply to#97361
On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
> > Andreas:
> >
> >> Hi all,
> [...]
> > Am I right in thinking  that  "Object-oriented  pro-
> > gramming in C":
> >
> >       http://www.cs.rit.edu/~ats/books/ooc.pdf
> >
> > is  based entirely on the violation of strict alias-
> > ing?
> 
> Well, I sort of like the following technique:
> 
> http://pastebin.com/f52a443b1
> 
> Not even trying to make full OOP, but its fairly nice...
> 
> ;^)

I tried looking at it, but I couldn't see the text under 
the failing-to-load Flash ads. Have you considered gist.github.com?
I find it infinitely superior to pastebin.

[toc] | [prev] | [next] | [standalone]


#97366 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2016-11-23 15:13 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<o157om$k6u$2@dont-email.me>
In reply to#97365
On 11/23/2016 3:10 PM, luser droog wrote:
> On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
>> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
>>> Andreas:
>>>
>>>> Hi all,
>> [...]
>>> Am I right in thinking  that  "Object-oriented  pro-
>>> gramming in C":
>>>
>>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
>>>
>>> is  based entirely on the violation of strict alias-
>>> ing?
>>
>> Well, I sort of like the following technique:
>>
>> http://pastebin.com/f52a443b1
>>
>> Not even trying to make full OOP, but its fairly nice...
>>
>> ;^)
>
> I tried looking at it, but I couldn't see the text under
> the failing-to-load Flash ads. Have you considered gist.github.com?
> I find it infinitely superior to pastebin.

Yikes! Okay, try this link:

http://pastebin.com/raw/f52a443b1

It should be raw text, also I will just post it here:
___________________________________________________
/* Interfaces
____________________________________________________________________*/
#include <stddef.h>


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 <stdio.h>
#include <stdlib.h>


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;
}
___________________________________________________


[toc] | [prev] | [next] | [standalone]


#97376 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

Fromluser droog <luser.droog@gmail.com>
Date2016-11-23 18:29 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<402285ed-26bb-42df-80a0-80ac9161bacd@googlegroups.com>
In reply to#97366
On Wednesday, November 23, 2016 at 5:13:45 PM UTC-6, Chris M. Thomasson wrote:
> On 11/23/2016 3:10 PM, luser droog wrote:
> > On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
> >> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
> >>> Andreas:
> >>>
> >>>> Hi all,
> >> [...]
> >>> Am I right in thinking  that  "Object-oriented  pro-
> >>> gramming in C":
> >>>
> >>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
> >>>
> >>> is  based entirely on the violation of strict alias-
> >>> ing?
> >>
> >> Well, I sort of like the following technique:
> >>
> >> http://pastebin.com/f52a443b1
> >>
> >> Not even trying to make full OOP, but its fairly nice...
> >>
> >> ;^)
> >
> > I tried looking at it, but I couldn't see the text under
> > the failing-to-load Flash ads. Have you considered gist.github.com?
> > I find it infinitely superior to pastebin.
> 
> Yikes! Okay, try this link:
> 
> http://pastebin.com/raw/f52a443b1
> 
> It should be raw text, also I will just post it here:
> ___________________________________________________
<snip>

Excellent. Thanks for the help. I like it. Inheritance by
composition is the current fav AFAIAA from OOP blogs.

I wonder if some of the void* could be written as their 
actual types (or superclass type as appropriate) for more
meaning to the reader, if not type-safety per se, ipso facto.

[toc] | [prev] | [next] | [standalone]


#97381 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2016-11-24 11:41 +0300
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<20161124114112.a967cf16b075fe89a489e4a4@g{oogle}mail.com>
In reply to#97366
Chris M. Thomasson qutoing
http://pastebin.com/raw/f52a443b1 :

>#include <stddef.h>
>
>
>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)) \
>)

What  is the point of separating object- and device-
related functions -- having the same "object" inter-
face  (  destroy()  ) to different types of objects,
i.e. to objects  with  different  sets  of  specific
functions?

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#97382 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromThiago Adams <thiago.adams@gmail.com>
Date2016-11-24 03:29 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<4d9a9da5-e36e-4658-a5a2-c3bdbca7b123@googlegroups.com>
In reply to#97366
On Wednesday, November 23, 2016 at 9:13:45 PM UTC-2, Chris M. Thomasson wrote:
> On 11/23/2016 3:10 PM, luser droog wrote:
> > On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
> >> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
> >>> Andreas:
> >>>
> >>>> Hi all,
> >> [...]
> >>> Am I right in thinking  that  "Object-oriented  pro-
> >>> gramming in C":
> >>>
> >>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
> >>>
> >>> is  based entirely on the violation of strict alias-
> >>> ing?
> >>
> >> Well, I sort of like the following technique:
> >>
> >> http://pastebin.com/f52a443b1

This is like the C++ implementation. I think this is the classic approach of java, C#, C++. The idea of "Interfaces".

The problem with interfaces (virtual functions) is the coupling caused by the interfaces. You cannot solve problems independently from each other; instead, you have to deal with the best set of interfaces that fits the algorithms you have so far. When you need to add or remove algorithms then you have to refactoring your interfaces for the best set again, and doing this, sometimes, can break code that is already working. It is very easy to increase coupling with interfaces, and it's hard to keep the interface sets correct. When you do it, probably the interfaces are useful only in your specific project making your classes less reusable.


[toc] | [prev] | [next] | [standalone]


#97442 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2016-11-24 17:37 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<o184hq$oi9$1@dont-email.me>
In reply to#97382
On 11/24/2016 3:29 AM, Thiago Adams wrote:
> On Wednesday, November 23, 2016 at 9:13:45 PM UTC-2, Chris M. Thomasson wrote:
>> On 11/23/2016 3:10 PM, luser droog wrote:
>>> On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
>>>> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
>>>>> Andreas:
>>>>>
>>>>>> Hi all,
>>>> [...]
>>>>> Am I right in thinking  that  "Object-oriented  pro-
>>>>> gramming in C":
>>>>>
>>>>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
>>>>>
>>>>> is  based entirely on the violation of strict alias-
>>>>> ing?
>>>>
>>>> Well, I sort of like the following technique:
>>>>
>>>> http://pastebin.com/f52a443b1
>
> This is like the C++ implementation. I think this is the classic approach of java, C#, C++. The idea of "Interfaces".
>
> The problem with interfaces (virtual functions) is the coupling caused by the interfaces. You cannot solve problems independently from each other; instead, you have to deal with the best set of interfaces that fits the algorithms you have so far. When you need to add or remove algorithms then you have to refactoring your interfaces for the best set again, and doing this, sometimes, can break code that is already working. It is very easy to increase coupling with interfaces, and it's hard to keep the interface sets correct. When you do it, probably the interfaces are useful only in your specific project making your classes less reusable.

You are correct: There is a hard core binding with the interface API. 
How to make API flexible in this type of scheme? Well, it was never 
meant to be full OOP, so perhaps the inflexible can become flexible 
within the realm of certain narrow use cases? I did not want to add more 
forms of indirection...

;^o

[toc] | [prev] | [next] | [standalone]


#97469 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

Fromsupercat@casperkitty.com
Date2016-11-25 09:55 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<4722afe4-e433-4784-bfa7-99e14b6376e7@googlegroups.com>
In reply to#97442
On Thursday, November 24, 2016 at 7:37:18 PM UTC-6, Chris M. Thomasson wrote:
> You are correct: There is a hard core binding with the interface API. 
> How to make API flexible in this type of scheme? Well, it was never 
> meant to be full OOP, so perhaps the inflexible can become flexible 
> within the realm of certain narrow use cases? I did not want to add more 
> forms of indirection...

If a compiler treats pointers to any kind of struct as interchangeable for
purposes of aliasing, the Common Initial Sequence rule, or function-pointer
signature compatibility, that will allow things to be written very nicely:

    struct baseThingFuncs { 
      void (*act1)(struct baseThing *it);
    }
    struct derived1Funcs {
      void (*act1)(struct derived1 *it);
      void (*act2)(struct derived1 *it);
    }

    struct baseThing { struct baseThingFuncs *f; int prop1, prop2; }
    struct derived1 { struct derived1Funcs *f; int prop1, prop2, prop3; }

Code which has a pointer p of type struct baseThing* would be able to
invoke act1 upon it via p->f->act1(p), but if *p was a derived1, it
would be able to use all the members of derived1 or derived1Funcs without
needing a cast.

Nice and elegant, if one is willing to use the dialect of C associated with
the -fno-strict-aliasing flag.

[toc] | [prev] | [next] | [standalone]


#97488 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromThiago Adams <thiago.adams@gmail.com>
Date2016-11-25 15:22 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<3d027f75-4a7c-4003-8801-b1e47594c583@googlegroups.com>
In reply to#97442
On Thursday, November 24, 2016 at 11:37:18 PM UTC-2, Chris M. Thomasson wrote:
> On 11/24/2016 3:29 AM, Thiago Adams wrote:
> > On Wednesday, November 23, 2016 at 9:13:45 PM UTC-2, Chris M. Thomasson wrote:
> >> On 11/23/2016 3:10 PM, luser droog wrote:
> >>> On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
> >>>> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
> >>>>> Andreas:
> >>>>>
> >>>>>> Hi all,
> >>>> [...]
> >>>>> Am I right in thinking  that  "Object-oriented  pro-
> >>>>> gramming in C":
> >>>>>
> >>>>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
> >>>>>
> >>>>> is  based entirely on the violation of strict alias-
> >>>>> ing?
> >>>>
> >>>> Well, I sort of like the following technique:
> >>>>
> >>>> http://pastebin.com/f52a443b1
> >
> > This is like the C++ implementation. I think this is the classic approach of java, C#, C++. The idea of "Interfaces".
> >
> > The problem with interfaces (virtual functions) is the coupling caused by the interfaces. You cannot solve problems independently from each other; instead, you have to deal with the best set of interfaces that fits the algorithms you have so far. When you need to add or remove algorithms then you have to refactoring your interfaces for the best set again, and doing this, sometimes, can break code that is already working. It is very easy to increase coupling with interfaces, and it's hard to keep the interface sets correct. When you do it, probably the interfaces are useful only in your specific project making your classes less reusable.
> 
> You are correct: There is a hard core binding with the interface API. 
> How to make API flexible in this type of scheme? Well, it was never 
> meant to be full OOP, so perhaps the inflexible can become flexible 
> within the realm of certain narrow use cases? I did not want to add more 
> forms of indirection...
> 
The problem of interfaces I mentioned is not a implementation problem, but a conceptual one.

The "interface" approach is useful when you don't want to know the concrete type. For instance, you want to create an algorithm that works with no change with the code someone else will give to you and the only thing you know is that the code uses the same interface pointers. "plugin"

I have a name for these polymorphism. 
I call it "open polymorphism"

In case I know all the types I call "closed polymorphism"

The closed polymorphism I implement using run-time selection using a number to identify the type. It is faster than vtable.

The open polymorphism I use  vtable-style.

In C, because there is nothing ready to use, I have many other variations that are better in different cases like unions kind of "variant type"



[toc] | [prev] | [next] | [standalone]


#97704 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2016-11-28 18:18 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<o1ioeg$gp3$1@dont-email.me>
In reply to#97488
On 11/25/2016 3:22 PM, Thiago Adams wrote:
> On Thursday, November 24, 2016 at 11:37:18 PM UTC-2, Chris M. Thomasson wrote:
>> On 11/24/2016 3:29 AM, Thiago Adams wrote:
>>> On Wednesday, November 23, 2016 at 9:13:45 PM UTC-2, Chris M. Thomasson wrote:
>>>> On 11/23/2016 3:10 PM, luser droog wrote:
>>>>> On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
>>>>>> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
>>>>>>> Andreas:
>>>>>>>
>>>>>>>> Hi all,
>>>>>> [...]
>>>>>>> Am I right in thinking  that  "Object-oriented  pro-
>>>>>>> gramming in C":
>>>>>>>
>>>>>>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
>>>>>>>
>>>>>>> is  based entirely on the violation of strict alias-
>>>>>>> ing?
>>>>>>
>>>>>> Well, I sort of like the following technique:
>>>>>>
>>>>>> http://pastebin.com/f52a443b1
>>>
>>> This is like the C++ implementation. I think this is the classic approach of java, C#, C++. The idea of "Interfaces".
>>>
>>> The problem with interfaces (virtual functions) is the coupling caused by the interfaces. You cannot solve problems independently from each other; instead, you have to deal with the best set of interfaces that fits the algorithms you have so far. When you need to add or remove algorithms then you have to refactoring your interfaces for the best set again, and doing this, sometimes, can break code that is already working. It is very easy to increase coupling with interfaces, and it's hard to keep the interface sets correct. When you do it, probably the interfaces are useful only in your specific project making your classes less reusable.
>>
>> You are correct: There is a hard core binding with the interface API.
>> How to make API flexible in this type of scheme? Well, it was never
>> meant to be full OOP, so perhaps the inflexible can become flexible
>> within the realm of certain narrow use cases? I did not want to add more
>> forms of indirection...
>>
> The problem of interfaces I mentioned is not a implementation problem, but a conceptual one.
>
> The "interface" approach is useful when you don't want to know the concrete type. For instance, you want to create an algorithm that works with no change with the code someone else will give to you and the only thing you know is that the code uses the same interface pointers. "plugin"
>
> I have a name for these polymorphism.
> I call it "open polymorphism"
>
> In case I know all the types I call "closed polymorphism"
>
> The closed polymorphism I implement using run-time selection using a number to identify the type. It is faster than vtable.

How are you doing this selection/dispatch?

>
> The open polymorphism I use  vtable-style.
>
> In C, because there is nothing ready to use, I have many other variations that are better in different cases like unions kind of "variant type"

Reminds me of the XEvent union in X11.

[toc] | [prev] | [next] | [standalone]


#97727 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromThiago Adams <thiago.adams@gmail.com>
Date2016-11-29 04:48 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<a644cb1a-04d9-4028-b413-be7458f91f84@googlegroups.com>
In reply to#97704
On Tuesday, November 29, 2016 at 12:18:12 AM UTC-2, Chris M. Thomasson wrote:
> On 11/25/2016 3:22 PM, Thiago Adams wrote:
> > On Thursday, November 24, 2016 at 11:37:18 PM UTC-2, Chris M. Thomasson wrote:
> >> On 11/24/2016 3:29 AM, Thiago Adams wrote:
> >>> On Wednesday, November 23, 2016 at 9:13:45 PM UTC-2, Chris M. Thomasson wrote:
> >>>> On 11/23/2016 3:10 PM, luser droog wrote:
> >>>>> On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
> >>>>>> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
> >>>>>>> Andreas:
> >>>>>>>
> >>>>>>>> Hi all,
> >>>>>> [...]
> >>>>>>> Am I right in thinking  that  "Object-oriented  pro-
> >>>>>>> gramming in C":
> >>>>>>>
> >>>>>>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
> >>>>>>>
> >>>>>>> is  based entirely on the violation of strict alias-
> >>>>>>> ing?
> >>>>>>
> >>>>>> Well, I sort of like the following technique:
> >>>>>>
> >>>>>> http://pastebin.com/f52a443b1
> >>>
> >>> This is like the C++ implementation. I think this is the classic approach of java, C#, C++. The idea of "Interfaces".
> >>>
> >>> The problem with interfaces (virtual functions) is the coupling caused by the interfaces. You cannot solve problems independently from each other; instead, you have to deal with the best set of interfaces that fits the algorithms you have so far. When you need to add or remove algorithms then you have to refactoring your interfaces for the best set again, and doing this, sometimes, can break code that is already working. It is very easy to increase coupling with interfaces, and it's hard to keep the interface sets correct. When you do it, probably the interfaces are useful only in your specific project making your classes less reusable.
> >>
> >> You are correct: There is a hard core binding with the interface API.
> >> How to make API flexible in this type of scheme? Well, it was never
> >> meant to be full OOP, so perhaps the inflexible can become flexible
> >> within the realm of certain narrow use cases? I did not want to add more
> >> forms of indirection...
> >>
> > The problem of interfaces I mentioned is not a implementation problem, but a conceptual one.
> >
> > The "interface" approach is useful when you don't want to know the concrete type. For instance, you want to create an algorithm that works with no change with the code someone else will give to you and the only thing you know is that the code uses the same interface pointers. "plugin"
> >
> > I have a name for these polymorphism.
> > I call it "open polymorphism"
> >
> > In case I know all the types I call "closed polymorphism"
> >
> > The closed polymorphism I implement using run-time selection using a number to identify the type. It is faster than vtable.
> 
> How are you doing this selection/dispatch?

like this:

typedef enum { Type1_ID, Type2_ID.. } Types;
typedef struct { Types Type; } TypePtr;
struct { TypePtr Type; ... } Type1;
#define TYPE1_INIT { {Type1_ID}, ... }
struct { TypePtr Type; ... } Type2;
#define TYPE2_INIT { {Type2_ID}, ... }


typedef TypePtr Shape;
CAST(Shape, Type1);
CAST(Shape, Type2);

#define Case(T)  case T_##ID:
 
void Shape_Print(Shape* p)
{
   switch (p->Type)
   {
      Case(Type1): 
        Type1_Print((Type1*)p); 
      break;
      
      Case(Type2): 
        Type2_Print((Type2*)p); 
       break;

      default:
       assert(false); 
      break;
   }
}

//I guess here is the controversial point of this topic
//(this works for me)
 
#define CAST(T1, T2)  \
inline T2* T1_##As##_T2(T1* p) { \
  return (p->Type == T2_##ID) ?  (T2*)p : 0;\
}\
inline T1* T2_##As##_T1(T2* p) { return (T1*)p; }


----

How it differs from vtable-style?

Let's say I have Circle and Cat objects.
The initial design was IObject, IAnimal, IShape.
Now I have to add a new algorithm Print. 
It was not at the initial design. Where do I add it now?
Do I put inside the IObject interface or I create a new Interface IPrintable?
The puzzle of interface definition begins and it's not a localized/independent problem.
To add a Print into the IObject interface I have to see if it makes sense for all objects derived from IObject. 
Lets see other case. I have IControl that is a interface for widgets. 
Initially I put the method "Draw" at this interface because all of my objects derived from IControl had to be drawn.
At some point, I have to add a new object similar of IControl but that doesn't need to be draw. 
Then I have to create a new interface called IDraw and move Draw from IControl to IDraw.  
When a new algorithm needs to be added I may have to reorganize the Interfaces and the types.
The types are now depending on many interfaces adjusted for the needs of that program globally adjusted.


With this type-selection approach you can solve the problem locally at the collection point. (you can think in small parts)

For instance, for the IControl "Draw" problem I can adjust my for-each-draw to just ignore the new type that doesn't need to be draw.
The new type, or the old ones don't need any changes.


You can create a new specialized algorithm as well without to worry about the interface relationship.
You can have many types of Print algorithms applied differently for different types without to worry it that type is for all types or not.
And you can reuse a type. If you don't need polymorphism just remove 1 line from the begging of you struct and you are done.

But with this approach you cannot add a new type without to change the algorithm. Or a new unknown type in some collection. "plugins"

--
What a language could do is to create the type selection for us.

Imagine a new language:

typedef (Box | Circle) Shape;

void Func(Shape* p)
{
   //we known that shape can be only Box or Circle
   // "closed polymorphism"

   //please language make this dispatch for me
   Shape_Draw(p);
}

void Box_Draw(Box* p) {...}
void Circle_Draw(Circle* p) {...}






[toc] | [prev] | [next] | [standalone]


#97734 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

Fromsupercat@casperkitty.com
Date2016-11-29 07:28 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<453f371f-5ce3-4848-abd0-e2cf0341d23f@googlegroups.com>
In reply to#97727
On Tuesday, November 29, 2016 at 6:48:48 AM UTC-6, Thiago Adams wrote:
> Now I have to add a new algorithm Print. 
> It was not at the initial design. Where do I add it now?

If things are added in a well-defined sequence, such that there will be an
entity that knows all the functions, then it will be possible to have code
which was compiled earlier pass its function and its size to the all-knowing
entity, and ask it to allocate and return a pointer to a table which includes
all functions the entity knows about.  If the all-knowing entity knows of a
print function, but it's given a table which doesn't include it, it could
fill in the "print" slot with either a stub that returns an error, or with a
function that uses some supported method of rendering to generate an image
of the object and then uses its own logic to print that.

[toc] | [prev] | [next] | [standalone]


#97780 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromThiago Adams <thiago.adams@gmail.com>
Date2016-11-30 08:26 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<2924507a-f8c4-447c-bd1d-c15fb1ac1e46@googlegroups.com>
In reply to#97734
On Tuesday, November 29, 2016 at 1:28:39 PM UTC-2, supe...@casperkitty.com wrote:
> On Tuesday, November 29, 2016 at 6:48:48 AM UTC-6, Thiago Adams wrote:
> > Now I have to add a new algorithm Print. 
> > It was not at the initial design. Where do I add it now?
> 
> If things are added in a well-defined sequence, such that there will be an
> entity that knows all the functions, then it will be possible to have code
> which was compiled earlier pass its function and its size to the all-knowing
> entity, and ask it to allocate and return a pointer to a table which includes
> all functions the entity knows about.  If the all-knowing entity knows of a
> print function, but it's given a table which doesn't include it, it could
> fill in the "print" slot with either a stub that returns an error, or with a
> function that uses some supported method of rendering to generate an image
> of the object and then uses its own logic to print that.

Do you mean runtime-vtable-build? 





[toc] | [prev] | [next] | [standalone]


#97785 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

Fromsupercat@casperkitty.com
Date2016-11-30 09:13 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<60ba08e0-2bb8-447b-90bf-bee69f17e9a7@googlegroups.com>
In reply to#97780
On Wednesday, November 30, 2016 at 10:26:29 AM UTC-6, Thiago Adams wrote:
> On Tuesday, November 29, 2016 at 1:28:39 PM UTC-2, supercat wrote:
> > If things are added in a well-defined sequence, such that there will be an
> > entity that knows all the functions, then it will be possible to have code
> > which was compiled earlier pass its function and its size to the all-knowing
> > entity, and ask it to allocate and return a pointer to a table which includes
> > all functions the entity knows about.  If the all-knowing entity knows of a
> > print function, but it's given a table which doesn't include it, it could
> > fill in the "print" slot with either a stub that returns an error, or with a
> > function that uses some supported method of rendering to generate an image
> > of the object and then uses its own logic to print that.
> 
> Do you mean runtime-vtable-build?

In a sense, but many such systems also require runtime computation of
offsets.  If functions are added to the library in a fixed universally-
agreed-upon sequence, such that given any two versions of the vtable,
one will be a subset of the other, all offsets will be known at compile
time.  Consequently, there would be a one-time cost at system startup
but all code which used the vtables would run at full-speed [unlike some
dynamic-vtable-generation approaches where every function call would
require an extra variable fetch].

Actually, on many systems it would be possible to have a build step between
the compiler and linker which could look for symbols with certain magic
names and perform all the necessary adjustments at link time.  For example,
if every "class" declared a const vtable whose name followed a certain
convention and an extern vtable whose name was related to the first, a
tool could search all object files for definitions of the first form and
define suitably-expanded vtables of the second form.  The exact means by
which the utility would identify the contents of all the appropriate tables
would depend upon the system's object file format, of course.

[toc] | [prev] | [next] | [standalone]


#99161 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2016-12-12 16:44 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<o2ng71$rgt$1@dont-email.me>
In reply to#97727
On 11/29/2016 4:48 AM, Thiago Adams wrote:
> On Tuesday, November 29, 2016 at 12:18:12 AM UTC-2, Chris M. Thomasson wrote:
>> On 11/25/2016 3:22 PM, Thiago Adams wrote:
>>> On Thursday, November 24, 2016 at 11:37:18 PM UTC-2, Chris M. Thomasson wrote:
>>>> On 11/24/2016 3:29 AM, Thiago Adams wrote:
>>>>> On Wednesday, November 23, 2016 at 9:13:45 PM UTC-2, Chris M. Thomasson wrote:
>>>>>> On 11/23/2016 3:10 PM, luser droog wrote:
>>>>>>> On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
>>>>>>>> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
>>>>>>>>> Andreas:
>>>>>>>>>
>>>>>>>>>> Hi all,
>>>>>>>> [...]
>>>>>>>>> Am I right in thinking  that  "Object-oriented  pro-
>>>>>>>>> gramming in C":
>>>>>>>>>
>>>>>>>>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
>>>>>>>>>
>>>>>>>>> is  based entirely on the violation of strict alias-
>>>>>>>>> ing?
>>>>>>>>
>>>>>>>> Well, I sort of like the following technique:
>>>>>>>>
>>>>>>>> http://pastebin.com/f52a443b1
>>>>>
>>>>> This is like the C++ implementation. I think this is the classic approach of java, C#, C++. The idea of "Interfaces".
>>>>>
>>>>> The problem with interfaces (virtual functions) is the coupling caused by the interfaces. You cannot solve problems independently from each other; instead, you have to deal with the best set of interfaces that fits the algorithms you have so far. When you need to add or remove algorithms then you have to refactoring your interfaces for the best set again, and doing this, sometimes, can break code that is already working. It is very easy to increase coupling with interfaces, and it's hard to keep the interface sets correct. When you do it, probably the interfaces are useful only in your specific project making your classes less reusable.
>>>>
>>>> You are correct: There is a hard core binding with the interface API.
>>>> How to make API flexible in this type of scheme? Well, it was never
>>>> meant to be full OOP, so perhaps the inflexible can become flexible
>>>> within the realm of certain narrow use cases? I did not want to add more
>>>> forms of indirection...
>>>>
>>> The problem of interfaces I mentioned is not a implementation problem, but a conceptual one.
>>>
>>> The "interface" approach is useful when you don't want to know the concrete type. For instance, you want to create an algorithm that works with no change with the code someone else will give to you and the only thing you know is that the code uses the same interface pointers. "plugin"
>>>
>>> I have a name for these polymorphism.
>>> I call it "open polymorphism"
>>>
>>> In case I know all the types I call "closed polymorphism"
>>>
>>> The closed polymorphism I implement using run-time selection using a number to identify the type. It is faster than vtable.
>>
>> How are you doing this selection/dispatch?
>
> like this:
>
> typedef enum { Type1_ID, Type2_ID.. } Types;
> typedef struct { Types Type; } TypePtr;
> struct { TypePtr Type; ... } Type1;
> #define TYPE1_INIT { {Type1_ID}, ... }
> struct { TypePtr Type; ... } Type2;
> #define TYPE2_INIT { {Type2_ID}, ... }
>
>
> typedef TypePtr Shape;
> CAST(Shape, Type1);
> CAST(Shape, Type2);
>
> #define Case(T)  case T_##ID:
>
> void Shape_Print(Shape* p)
> {
>    switch (p->Type)
>    {
>       Case(Type1):
>         Type1_Print((Type1*)p);
>       break;
>
>       Case(Type2):
>         Type2_Print((Type2*)p);
>        break;
>
>       default:
>        assert(false);
>       break;
>    }
> }

I see. So, if we add a new Shape TypeN, we have to add a new entry here 
in Shape_Print and add a new entry wrt the CAST macro, right?. That's fine.



>
> //I guess here is the controversial point of this topic
> //(this works for me)
>
> #define CAST(T1, T2)  \
> inline T2* T1_##As##_T2(T1* p) { \
>   return (p->Type == T2_##ID) ?  (T2*)p : 0;\
> }\
> inline T1* T2_##As##_T1(T2* p) { return (T1*)p; }

Concat in pre-processor is fine.

>
>
> ----
>
> How it differs from vtable-style?
>
> Let's say I have Circle and Cat objects.
> The initial design was IObject, IAnimal, IShape.
> Now I have to add a new algorithm Print.
> It was not at the initial design. Where do I add it now?



> Do I put inside the IObject interface or I create a new Interface IPrintable?
> The puzzle of interface definition begins and it's not a localized/independent problem.
> To add a Print into the IObject interface I have to see if it makes sense for all objects derived from IObject.
> Lets see other case. I have IControl that is a interface for widgets.
> Initially I put the method "Draw" at this interface because all of my objects derived from IControl had to be drawn.
> At some point, I have to add a new object similar of IControl but that doesn't need to be draw.
> Then I have to create a new interface called IDraw and move Draw from IControl to IDraw.
> When a new algorithm needs to be added I may have to reorganize the Interfaces and the types.
> The types are now depending on many interfaces adjusted for the needs of that program globally adjusted.
>
>
> With this type-selection approach you can solve the problem locally at the collection point. (you can think in small parts)

I agree with you. Keep in mind that my little interface code worked 
great wrt my problem set. Think of testing a dozen mutex impls using a 
common interface for a "mutex".


>
> For instance, for the IControl "Draw" problem I can adjust my for-each-draw to just ignore the new type that doesn't need to be draw.
> The new type, or the old ones don't need any changes.
>
>
> You can create a new specialized algorithm as well without to worry about the interface relationship.
> You can have many types of Print algorithms applied differently for different types without to worry it that type is for all types or not.
> And you can reuse a type. If you don't need polymorphism just remove 1 line from the begging of you struct and you are done.
>
> But with this approach you cannot add a new type without to change the algorithm. Or a new unknown type in some collection. "plugins"

Yup. I have used the crude minimalist interface code for plugins. It 
works well, and keeps a standard interface for said plugins.


>
> --
> What a language could do is to create the type selection for us.
>
> Imagine a new language:
>
> typedef (Box | Circle) Shape;
>
> void Func(Shape* p)
> {
>    //we known that shape can be only Box or Circle
>    // "closed polymorphism"
>
>    //please language make this dispatch for me
>    Shape_Draw(p);
> }
>
> void Box_Draw(Box* p) {...}
> void Circle_Draw(Circle* p) {...}

Interesting.

:^)

[toc] | [prev] | [next] | [standalone]


#99168 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromMelzzzzz <mel@zzzzz.com>
Date2016-12-13 02:18 +0100
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<20161213021845.1779de2d@maxa-pc>
In reply to#99161
On Mon, 12 Dec 2016 16:44:37 -0800
"Chris M. Thomasson" <invalid@invalid.invalid> wrote:

> On 11/29/2016 4:48 AM, Thiago Adams wrote:
> >
> > --
> > What a language could do is to create the type selection for us.
> >
> > Imagine a new language:
> >
> > typedef (Box | Circle) Shape;
> >
> > void Func(Shape* p)
> > {
> >    //we known that shape can be only Box or Circle
> >    // "closed polymorphism"
> >
> >    //please language make this dispatch for me
> >    Shape_Draw(p);
> > }
> >
> > void Box_Draw(Box* p) {...}
> > void Circle_Draw(Circle* p) {...}  
> 
> Interesting.
> 
> :^)

Haskell:

data Shape = Circle Double | Rectangle Double Double | Square Double
 deriving (Show,Read)

perimeter (Circle r) = 2*r*pi
perimeter (Rectangle x y) = 2*(x+y)
perimeter (Square x) = 4*x

shapes = [Circle 2.4, Rectangle 3.1 4.4, Square 2.1]

main = do
 putStrLn $ show $ map perimeter shapes
 putStrLn $ show shapes


-- 
press any key to continue or any other to quit...

[toc] | [prev] | [next] | [standalone]


#99361 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromThiago Adams <thiago.adams@gmail.com>
Date2016-12-14 09:47 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<55a27566-b4e8-4b5f-bc41-3df3e8c7df9d@googlegroups.com>
In reply to#99161
On Monday, December 12, 2016 at 10:44:42 PM UTC-2, Chris M. Thomasson wrote:
> On 11/29/2016 4:48 AM, Thiago Adams wrote:
> > On Tuesday, November 29, 2016 at 12:18:12 AM UTC-2, Chris M. Thomasson wrote:
> >> On 11/25/2016 3:22 PM, Thiago Adams wrote:
> >>> On Thursday, November 24, 2016 at 11:37:18 PM UTC-2, Chris M. Thomasson wrote:
> >>>> On 11/24/2016 3:29 AM, Thiago Adams wrote:
> >>>>> On Wednesday, November 23, 2016 at 9:13:45 PM UTC-2, Chris M. Thomasson wrote:
> >>>>>> On 11/23/2016 3:10 PM, luser droog wrote:
> >>>>>>> On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
> >>>>>>>> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
> >>>>>>>>> Andreas:
> >>>>>>>>>
> >>>>>>>>>> Hi all,
> >>>>>>>> [...]
> >>>>>>>>> Am I right in thinking  that  "Object-oriented  pro-
> >>>>>>>>> gramming in C":
> >>>>>>>>>
> >>>>>>>>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
> >>>>>>>>>
> >>>>>>>>> is  based entirely on the violation of strict alias-
> >>>>>>>>> ing?
> >>>>>>>>
> >>>>>>>> Well, I sort of like the following technique:
> >>>>>>>>
> >>>>>>>> http://pastebin.com/f52a443b1
> >>>>>
> >>>>> This is like the C++ implementation. I think this is the classic approach of java, C#, C++. The idea of "Interfaces".
> >>>>>
> >>>>> The problem with interfaces (virtual functions) is the coupling caused by the interfaces. You cannot solve problems independently from each other; instead, you have to deal with the best set of interfaces that fits the algorithms you have so far. When you need to add or remove algorithms then you have to refactoring your interfaces for the best set again, and doing this, sometimes, can break code that is already working. It is very easy to increase coupling with interfaces, and it's hard to keep the interface sets correct. When you do it, probably the interfaces are useful only in your specific project making your classes less reusable.
> >>>>
> >>>> You are correct: There is a hard core binding with the interface API.
> >>>> How to make API flexible in this type of scheme? Well, it was never
> >>>> meant to be full OOP, so perhaps the inflexible can become flexible
> >>>> within the realm of certain narrow use cases? I did not want to add more
> >>>> forms of indirection...
> >>>>
> >>> The problem of interfaces I mentioned is not a implementation problem, but a conceptual one.
> >>>
> >>> The "interface" approach is useful when you don't want to know the concrete type. For instance, you want to create an algorithm that works with no change with the code someone else will give to you and the only thing you know is that the code uses the same interface pointers. "plugin"
> >>>
> >>> I have a name for these polymorphism.
> >>> I call it "open polymorphism"
> >>>
> >>> In case I know all the types I call "closed polymorphism"
> >>>
> >>> The closed polymorphism I implement using run-time selection using a number to identify the type. It is faster than vtable.
> >>
> >> How are you doing this selection/dispatch?
> >
> > like this:
> >
> > typedef enum { Type1_ID, Type2_ID.. } Types;
> > typedef struct { Types Type; } TypePtr;
> > struct { TypePtr Type; ... } Type1;
> > #define TYPE1_INIT { {Type1_ID}, ... }
> > struct { TypePtr Type; ... } Type2;
> > #define TYPE2_INIT { {Type2_ID}, ... }
> >
> >
> > typedef TypePtr Shape;
> > CAST(Shape, Type1);
> > CAST(Shape, Type2);
> >
> > #define Case(T)  case T_##ID:
> >
> > void Shape_Print(Shape* p)
> > {
> >    switch (p->Type)
> >    {
> >       Case(Type1):
> >         Type1_Print((Type1*)p);
> >       break;
> >
> >       Case(Type2):
> >         Type2_Print((Type2*)p);
> >        break;
> >
> >       default:
> >        assert(false);
> >       break;
> >    }
> > }
> 
> I see. So, if we add a new Shape TypeN, we have to add a new entry here 
> in Shape_Print and add a new entry wrt the CAST macro, right?. That's fine.


The cast macro, creates the cast functions. Because the language would not check any of the casts these functions have a very important role. If the function exists then the cast is valid.
The auto complete from IDEs also shows what are the valid casts when I type Shape_As_... I receive the options.


[toc] | [prev] | [next] | [standalone]


#99368 — Re: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]

FromThiago Adams <thiago.adams@gmail.com>
Date2016-12-14 10:14 -0800
SubjectRe: "Object-oriented programming in C" [was: Re: Aliasing and subtyping structs]
Message-ID<19bc0471-3f9b-43d2-b170-572dfab0077e@googlegroups.com>
In reply to#99361
On Wednesday, December 14, 2016 at 3:47:45 PM UTC-2, Thiago Adams wrote:
> On Monday, December 12, 2016 at 10:44:42 PM UTC-2, Chris M. Thomasson wrote:
> > On 11/29/2016 4:48 AM, Thiago Adams wrote:
> > > On Tuesday, November 29, 2016 at 12:18:12 AM UTC-2, Chris M. Thomasson wrote:
> > >> On 11/25/2016 3:22 PM, Thiago Adams wrote:
> > >>> On Thursday, November 24, 2016 at 11:37:18 PM UTC-2, Chris M. Thomasson wrote:
> > >>>> On 11/24/2016 3:29 AM, Thiago Adams wrote:
> > >>>>> On Wednesday, November 23, 2016 at 9:13:45 PM UTC-2, Chris M. Thomasson wrote:
> > >>>>>> On 11/23/2016 3:10 PM, luser droog wrote:
> > >>>>>>> On Wednesday, November 23, 2016 at 3:40:05 PM UTC-6, Chris M. Thomasson wrote:
> > >>>>>>>> On 11/21/2016 5:59 AM, Anton Shepelev wrote:
> > >>>>>>>>> Andreas:
> > >>>>>>>>>
> > >>>>>>>>>> Hi all,
> > >>>>>>>> [...]
> > >>>>>>>>> Am I right in thinking  that  "Object-oriented  pro-
> > >>>>>>>>> gramming in C":
> > >>>>>>>>>
> > >>>>>>>>>       http://www.cs.rit.edu/~ats/books/ooc.pdf
> > >>>>>>>>>
> > >>>>>>>>> is  based entirely on the violation of strict alias-
> > >>>>>>>>> ing?
> > >>>>>>>>
> > >>>>>>>> Well, I sort of like the following technique:
> > >>>>>>>>
> > >>>>>>>> http://pastebin.com/f52a443b1
> > >>>>>
> > >>>>> This is like the C++ implementation. I think this is the classic approach of java, C#, C++. The idea of "Interfaces".
> > >>>>>
> > >>>>> The problem with interfaces (virtual functions) is the coupling caused by the interfaces. You cannot solve problems independently from each other; instead, you have to deal with the best set of interfaces that fits the algorithms you have so far. When you need to add or remove algorithms then you have to refactoring your interfaces for the best set again, and doing this, sometimes, can break code that is already working. It is very easy to increase coupling with interfaces, and it's hard to keep the interface sets correct. When you do it, probably the interfaces are useful only in your specific project making your classes less reusable.
> > >>>>
> > >>>> You are correct: There is a hard core binding with the interface API.
> > >>>> How to make API flexible in this type of scheme? Well, it was never
> > >>>> meant to be full OOP, so perhaps the inflexible can become flexible
> > >>>> within the realm of certain narrow use cases? I did not want to add more
> > >>>> forms of indirection...
> > >>>>
> > >>> The problem of interfaces I mentioned is not a implementation problem, but a conceptual one.
> > >>>
> > >>> The "interface" approach is useful when you don't want to know the concrete type. For instance, you want to create an algorithm that works with no change with the code someone else will give to you and the only thing you know is that the code uses the same interface pointers. "plugin"
> > >>>
> > >>> I have a name for these polymorphism.
> > >>> I call it "open polymorphism"
> > >>>
> > >>> In case I know all the types I call "closed polymorphism"
> > >>>
> > >>> The closed polymorphism I implement using run-time selection using a number to identify the type. It is faster than vtable.
> > >>
> > >> How are you doing this selection/dispatch?
> > >
> > > like this:
> > >
> > > typedef enum { Type1_ID, Type2_ID.. } Types;
> > > typedef struct { Types Type; } TypePtr;
> > > struct { TypePtr Type; ... } Type1;
> > > #define TYPE1_INIT { {Type1_ID}, ... }
> > > struct { TypePtr Type; ... } Type2;
> > > #define TYPE2_INIT { {Type2_ID}, ... }
> > >
> > >
> > > typedef TypePtr Shape;
> > > CAST(Shape, Type1);
> > > CAST(Shape, Type2);
> > >
> > > #define Case(T)  case T_##ID:
> > >
> > > void Shape_Print(Shape* p)
> > > {
> > >    switch (p->Type)
> > >    {
> > >       Case(Type1):
> > >         Type1_Print((Type1*)p);
> > >       break;
> > >
> > >       Case(Type2):
> > >         Type2_Print((Type2*)p);
> > >        break;
> > >
> > >       default:
> > >        assert(false);
> > >       break;
> > >    }
> > > }
> > 
> > I see. So, if we add a new Shape TypeN, we have to add a new entry here 
> > in Shape_Print and add a new entry wrt the CAST macro, right?. That's fine.
> 
> 
> The cast macro, creates the cast functions. Because the language would not check any of the casts these functions have a very important role. If the function exists then the cast is valid.
> The auto complete from IDEs also shows what are the valid casts when I type Shape_As_... I receive the options.



Something interesting is that at some level I have to iterate myself on types to see what are the possible casts.

Some of the casts just logical renaming.

For instance:

Shape = Circle | Box;

Animal = Cat | Dog;

Anything = Shape | Animal;


The implementation of Anything, Shape and Animal are the same thing (TypePtr).

But I can cast Anything_As_Shape.

I also can cast Anything to Box, because Anything can be Shape that can be Box.

I am considering to create some DSL to create these casts for me.

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | comp.lang.c


csiph-web