
Object Oriented ANSI C (1993) [pdf] - tambourine_man
http://www.cs.rit.edu/~ats/books/ooc.pdf
======
kazinator
Use of void * for information hiding is a very poor idea because you lose type
checking. For example, the differ function in section 1.5 can easily be
misused without any diagnostic:

    
    
      int x, y, a[3];
      /*...*/
      differ("foo", "bar");
      differ(&x, &y);
      differ(a, a);
      differ(&a, &a);
    

Do not hide so much information that even the compiler is left in the dark!

To not reveal anything about how an object is implemented, use a pointer to an
incomplete struct, like

    
    
      typedef struct object object;
    
      int differ (const object *, const object *);

~~~
readerrrr
A full chapter is dedicated to dynamic type checking.

If that isn't acceptable for your project, don't use it. Successful languages
that don't have compile time checks, show that this problem is irrelevant.

~~~
kazinator
The argument is wrongheaded. Implementations of dynamically typed object
systems _in C_ do not benefit from using void * all over the place instead of
a typed object * pointer.

C itself isn't dynamic and it behooves you to use it as safely as possible if
you don't want your dynamically typed framework to fall apart due to easily
avoidable bugs.

Whereas you can have dynamic checking which tells you that some object *
pointer is a cons cell, vector, string or whatever, if you use void * instead,
the type check itself is threatened with undefined behavior:

    
    
       object *stringp(object *obj)
       {
         if (is_heap_object(obj) && obj->typecode == TYPE_STR)
           return t_obj;
         return nil_obj;
       }
    
       // ..
    
       {
         int x;
    
         if (stringp(&x)) ...  // compile-time error!
    
       }
    

If stringp has the signature

    
    
       void *stringp(void *obj);
    

then there is no compile time error; &x happily passes into the function.
Moreover, the function has to do an ugly conversion to recover a typed pointer
so it has to use it.

    
    
       void *stringp(void *obj_in)
       {
         object *obj = obj_in; // cast needed here in C++
    
         if (is_heap_object(obj) && obj->typecode = TYPE_STR)
    

Dynamic typing is a high level feature that is boostrapped from static typing
(whether that typing is checked by a compiler or not!) Static typing means
that a given piece of code working on a given piece of data correctly uses
that data. For instance if we write assembly code which extracts the bottom
three bits of a word, and treats that as a type tag, that is static typing:
it's a static fact of the program that that code operates on data with a three
bit type tag, and if it is given something else by accident, like a floating-
point value without a type tag, it will misbehave.

In short, something has to be rigid at the bottom-most layer. C has enough
type muscle to help with that quite a bit without getting in the way too much.

------
_RPM
This is interesting literature. I haven't had the patience to sit down and
completely read it word for word, but I have skimmed through it a few months
ago.

It seems that this would be a great way to learn about how to create an object
model in C for your own programming language.

And I might be wrong, but reading this inspires me to create my own toy
language and virtual machine for educational purposes just because I am
interested in it, not to create the next cool language.

------
aikah
Thanks !This book looks fantastic.I'm not very good at C but it will be an
interesting exercise to model a OO system in that language.

~~~
readerrrr
It has a very high learning curve. And while it has great ideas, the usage of
variadic functions is not warranted in my opinion.

I recommend you first try a simple OO project yourself.

------
jhallenworld
I wrote a widget library for X using "object oriented" C. It implements single
inheritance using preprocessor tricks: [https://github.com/jhallen/joes-
sandbox/tree/master/x/notif](https://github.com/jhallen/joes-
sandbox/tree/master/x/notif)

------
wsc981
Reading chapter 7 it's quite easy to understand that Objective-C once started
as a preprocessor for C.

~~~
andyjohnson0
That's also how C++ started. The original C++ compiler, cfront [1], converted
C++ source to C source which it then passed to cc.

[1] [http://en.wikipedia.org/wiki/Cfront](http://en.wikipedia.org/wiki/Cfront)

------
ExpiredLink
This is the old abysmal Schreiner book. I don't know why this is re-posted
from time to time. Better look here:
[http://nullprogram.com/blog/2014/10/21/](http://nullprogram.com/blog/2014/10/21/)
(discussion here:
[http://www.reddit.com/r/programming/comments/2mndod/c_object...](http://www.reddit.com/r/programming/comments/2mndod/c_object_oriented_programming/)
)

~~~
readerrrr
That is a very limited system without real polymorphism.

