Object-oriented programming in standard ANSI C

R

Roland Pibinger

Unfortunately, your approach precludes automatic function inlining.

No encapsulation means no OO. You can't have both at the same time :)
This would preclude any explicit call to function actualShape_draw.
An optimizing C++ compiler will elide the virtual {messenger} function
and call the actual function directly if it can determine the actual
type at compile time.

But isn't polymorphism the point of the whole exercise?

Best regards,
Roland Pibinger
 
E

E. Robert Tisdale

Roland Pibinger wrote;
No encapsulation means no OO. You can't have both at the same time :)

You probably meant "data hiding".
The C computer programming language allows you to encapsulate data
[in a struct] but it doesn't support data hiding at all.
Using an opaque data types
(publishing a struct declaration without publishing it's definition)
precludes some compile time optimizations.
But isn't polymorphism the point of the whole exercise?

Yes, but there is no reason
why that should preclude non-polymorphic applications.
 
K

Keith Thompson

E. Robert Tisdale said:
You probably meant "data hiding".
The C computer programming language allows you to encapsulate data
[in a struct] but it doesn't support data hiding at all.

It doesn't? At all?
Using an opaque data types
(publishing a struct declaration without publishing it's definition)
precludes some compile time optimizations.

Ah, so it *does* support data hiding.
 
C

Chris Thomasson

Chris Thomasson a écrit :
Hi,
I'm interested in techniques used to program in an object-oriented way
using the C ANSI language.
[...]
Are you aware of another approaches?
[...]
Check this crap out:

http://groups.google.com/group/comp.lang.c/msg/6cf857051ca4029b "Thierry Chappuis"
Thank you for the link! Bookmarked!

No problem... The technique works very well, IMHO. Its a quick, clear and
clean method for supporting basic OO programming in pure ANSI C. I like it
better than C++ in some respects; I am a C/Assembly Language programmer at
heart...

;^)
 
R

Roland Pibinger

:
[...]
You probably meant "data hiding".
The C computer programming language allows you to encapsulate data
[in a struct] but it doesn't support data hiding at all.

There have been many discussions whether encapsulation and information
hiding are the same or whether one is a means for the other. Let's
assume we mean that data should not be accessible from the 'outside'.
It doesn't? At all?


Ah, so it *does* support data hiding.

I've always wondered why C programmers often unnecessarily give up
encapsulation. You can frequently see code like the following:

struct my_struct {
// some data
};
typedef struct my_struct my_struct;

my_struct* init (int i);
int do_something (my_struct* p, int n, float f);
// more functions
void cleanup (my_struct* p);

In the above example the my_struct definition in the header file is
unnecessary, a forward declaration (struct my_struct;) is sufficient.
The user not only gets access to 'private' data but also the my_struct
data become part of the published interface. This means that future
releases of the code cannot alter that data any more (not even
rearrange them) without potentially breaking existing code. Sometimes
the (generous) use of macros prevents encapsulation but in many cases
lack of encapsulation seems to be just an oversight of the programmer.

Best regards,
Roland Pibinger
 
E

E. Robert Tisdale

Roland said:
I've always wondered
why C programmers often unnecessarily give up encapsulation.
You can frequently see code like the following:

struct my_struct {
// some data
};
typedef struct my_struct my_struct;

my_struct* init (int i);
int do_something (my_struct* p, int n, float f);
// more functions
void cleanup (my_struct* p);

In the above example,
the my_struct definition in the header file is unnecessary.
A forward declaration (struct my_struct;) is sufficient.
The user not only gets access to 'private' data but, also,
the my_struct data become part of the published interface.
This means that future releases of the code cannot alter that data any more
(not even rearrange them) without potentially breaking existing code.
Sometimes the (generous) use of macros prevents encapsulation but, in many cases,
lack of encapsulation seems to be just an oversight of the programmer.

This is poor programming practice.
It compels the programmer to create an uninitialized variable.

It would be better to define a pseudo-constructor

inline
my_struct my_struct_create(int i) {
my_struct value;
// initialize value
return value;
}

and a destructor

inline
void my_struct_destroy(const my_struct* p) {
}


which you might use like this

const
my_struct t = my_struct(13);

// . . .

my_struct_destroy(&t);

Function do_something should not modify *p
and should be declared as

inline
int do_something (const my_struct* p, int n, float f);

If the object really is a container,
you must provide methods that permit users to modify them.

This is a lot safer and more reliable than the methods
that you have suggested. It also allows the C compiler
to inline the functions to improve performance and efficiency.


The C computer programming language does not support data hiding.
Opaque data types may preclude certain optimizations.
 
C

Chris Thomasson

Roland Pibinger said:
:
[...]
You probably meant "data hiding".
The C computer programming language allows you to encapsulate data
[in a struct] but it doesn't support data hiding at all.

There have been many discussions whether encapsulation and information
hiding are the same or whether one is a means for the other. Let's
assume we mean that data should not be accessible from the 'outside'.
It doesn't? At all?


Ah, so it *does* support data hiding.

I've always wondered why C programmers often unnecessarily give up
encapsulation. You can frequently see code like the following:

struct my_struct {
// some data
};
typedef struct my_struct my_struct;

[...]


header
----------

typedef struct mystuff_s *mystuff_t;

extern int mystuff_alloc(mystuff_t*, /* config */);
/* whatever */


source
----------

#include "header"
struct mystuff_s {
/* whatever */
};


int mystuff_alloc(mystuff_t *_pthis, /* config */) {
if (_pthis && /* config is valid */) {
mystuff_t _this = malloc(sizeof(*_this));
if (_this) {
if (/* config of '_this' succeeds */) {
*_pthis = _this;
return 1;
}
}
free(_this);
}

return 0;
}

/* whatever */



It's that simple to hide data-structures that are too sensitive to be in the
hands of a user... Of course "they" can disassemble your code and figure
things out real good, then create a definition of your data-structure(s) for
themselves... Nothing is "crowbar" proof here... Its as simple as following
your pointer and recording all of the offsets from every load/store that
deals with it...

;^)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,138
Latest member
NevilleLam
Top