473,657 Members | 2,422 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Too much encapsulation?

I have recently read "Everything you ever wanted to know about C types" by
Peter Seebach (1), and learned about incomplete types. Now, I realise the
value of encapsulation, but I wonder whether it is proper C style to use
that much of it. By using incomplete types you end up with something like
this:

object_set_colo ur(object, RED);
colour = object_get_colo ur(object);

instead of:

object->colour = RED;
colour = object->colour;

If the type of "object" is incomplete, you could not write object->colour or
something like that, because accessing data of incomplete type is not
possible. Only the file which contains the get/set rountines defines the
type. You end up with something that looks very much like OOP + a terrible
overhead. Keep in mind that you need to keep the get/set functions + the
actual type definition in a seperate file to get the encapsulation effect.
That means that no mainstream C compiler will be able to optimize those
function calls away (AFAIK neither GNU, nor MS, nor Borland can inline
functions from other files).

So do you consider that proper C style?
Personally, I am not sure what to think of this. It seems to scream "Why do
you not use C++ already?!".

Link:
http://www-128.ibm.com/developerwork...&Search=Search

Jun 14 '07 #1
16 2128
On Jun 14, 3:28 pm, "copx" <c...@gazeta.pl wrote:
I have recently read "Everything you ever wanted to know about C types" by
Peter Seebach (1), and learned about incomplete types. Now, I realise the
value of encapsulation, but I wonder whether it is proper C style to use
that much of it. By using incomplete types you end up with something like
this:

object_set_colo ur(object, RED);
colour = object_get_colo ur(object);

instead of:

object->colour = RED;
colour = object->colour;

If the type of "object" is incomplete, you could not write object->colour or
something like that, because accessing data of incomplete type is not
possible. Only the file which contains the get/set rountines defines the
type. You end up with something that looks very much like OOP + a terrible
overhead. Keep in mind that you need to keep the get/set functions + the
actual type definition in a seperate file to get the encapsulation effect.
That means that no mainstream C compiler will be able to optimize those
function calls away (AFAIK neither GNU, nor MS, nor Borland can inline
functions from other files).
MS VC++ can do it.
And if you do the cheesy, sleezy include trick all of them can do it:

/* main.c starts here... */
#include "file1.c"
#include "file2.c"
#include "file3.c"
#include "file4.c"
#include "file5.c"
int main(void)
{
return some_important_ function();
}
/* main.c ends here... */
So do you consider that proper C style?
Personally, I am not sure what to think of this. It seems to scream "Why do
you not use C++ already?!".

Link:http://www-128.ibm.com/developerwork...lts.jsp?search...
If I want C++, then I code in C++.

If I want to write a Unix style filter, I will use C.

On the other hand, I have no problem reading or even enjoying C code
written in a C++ style.

On the other, other hand, I have seen programs where everything is
typedef-ed into some abstract type (even things like loop indexes) and
find those programs to be a lot less transparent to understand than
one more simply written.

IMO-YMMV.
Jun 14 '07 #2
"copx" <co**@gazeta.pl writes:
I have recently read "Everything you ever wanted to know about C types" by
Peter Seebach (1), and learned about incomplete types. Now, I realise the
value of encapsulation, but I wonder whether it is proper C style to use
that much of it. By using incomplete types you end up with something like
this:

object_set_colo ur(object, RED);
colour = object_get_colo ur(object);
If you end up with this you don't really *have* any encapsulation.
All you've done invent new syntax for:
instead of:

object->colour = RED;
colour = object->colour;
as you have spotted.

Incomplete types are at their most useful when the interface you have
to define is small compared to the complexity (or probable
variability) of the implementation that is hidden behind it.

--
Ben.
Jun 15 '07 #3
copx wrote:
I have recently read "Everything you ever wanted to know about C types" by
Peter Seebach (1), and learned about incomplete types. Now, I realise the
value of encapsulation, but I wonder whether it is proper C style to use
that much of it. By using incomplete types you end up with something like
this:

object_set_colo ur(object, RED);
colour = object_get_colo ur(object);

instead of:

object->colour = RED;
colour = object->colour;

If the type of "object" is incomplete, you could not write object->colour or
something like that, because accessing data of incomplete type is not
possible. Only the file which contains the get/set rountines defines the
type. You end up with something that looks very much like OOP + a terrible
overhead. Keep in mind that you need to keep the get/set functions + the
actual type definition in a seperate file to get the encapsulation effect.
That means that no mainstream C compiler will be able to optimize those
function calls away (AFAIK neither GNU, nor MS, nor Borland can inline
functions from other files).

So do you consider that proper C style?
Yes, and it's a very common idiom (have you ever manipulated a FILE
object?). Sometimes you want to use encapsulation to present a
consistent interface over a number of platforms. Other times you may
wish to provide a stable interface to an object that is liable to change
between releases of you application.
Personally, I am not sure what to think of this. It seems to scream "Why do
you not use C++ already?!".
Nothing to do with C++, unless you are using a similar idiom with opaque
types, C++ classes lay their innards bare for all to see.

--
Ian Collins.
Jun 15 '07 #4
copx wrote:
I have recently read "Everything you ever wanted to know about C types" by
Peter Seebach (1), and learned about incomplete types. Now, I realise the
value of encapsulation, but I wonder whether it is proper C style to use
that much of it. By using incomplete types you end up with something like
this:

object_set_colo ur(object, RED);
colour = object_get_colo ur(object);

instead of:

object->colour = RED;
colour = object->colour;

If the type of "object" is incomplete, you could not write object->colour or
something like that, because accessing data of incomplete type is not
possible. Only the file which contains the get/set rountines defines the
type. You end up with something that looks very much like OOP + a terrible
overhead. Keep in mind that you need to keep the get/set functions + the
actual type definition in a seperate file to get the encapsulation effect.
That means that no mainstream C compiler will be able to optimize those
function calls away (AFAIK neither GNU, nor MS, nor Borland can inline
functions from other files).

So do you consider that proper C style?
"Proper" is a judgmental term I won't try to address.
As for the pattern, yes: It's a perfectly good and useful
way to use C. Let's modify your example a little bit:

colour_set_rgb( &hue, RED, 1.0); /* RED to 100% */
cyan = colour_get_cmy( &hue, CYAN); /* get CYAN value */

That is, suppose there is a colour object that supports several
different perceptual color models: RGB, CMY, CMYK, CIE, ... You
can set the components of any model, and read back the components
of any other model: the object takes care of the transformations .
You can even do mixed-mode operations:

colour_set_rgb( &hue, RED, 1.0); /* red to the max */
colour_set_hsv( &hue, VAL, 0.2); /* ... but make it dim */
black = colour_get_cmyk (&hue, BLACK); /* how much black? */

Now: How are you going to accomplish this with the struct->element
approach? By using mutators and accessors, you give yourself an
opportunity to do some processing at interesting moments, to
defend against bogus settings (colour_set_rgb (&hue, RED, -42e9)),
and in general to change the internal representation of the object.

This freedom isn't always important, and it's silly to be a
slave to encapsulation orthodoxy for no purpose. But it can also
be a potent tool, capable of simplifying designs and easing
debugging. The trick is to know when to indulge and when to
abstain.
Personally, I am not sure what to think of this. It seems to scream "Why do
you not use C++ already?!".
Because you'll go straight to Hell, of course. Where your
body, like your name, will be mangled.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jun 15 '07 #5
"copx" <co**@gazeta.pl wrote in message
news:f4******** **@inews.gazeta .pl...
>I have recently read "Everything you ever wanted to know about C types" by
Peter Seebach (1), and learned about incomplete types. Now, I realise the
value of encapsulation, but I wonder whether it is proper C style to use
that much of it. By using incomplete types you end up with something like
this:

object_set_colo ur(object, RED);
colour = object_get_colo ur(object);

instead of:

object->colour = RED;
colour = object->colour;

If the type of "object" is incomplete, you could not write object->colour
or something like that, because accessing data of incomplete type is not
possible. Only the file which contains the get/set rountines defines the
type.
That's one way to do it, in particular if you're writing a library to be
used by others and there's a substantial risk that versions will get out of
sync (for instance, you change your library code but they don't recompile
their application).

The other way to do it is to define function-like macros or static inline
functions in the header file that the application includes, which allows the
compiler to optimize away the encapsulation. This is safe as long as you
trust coders using your interface not to peek at the implementation and both
sets of code will always be recompiled if you change the internals.
You end up with something that looks very much like OOP + a terrible
overhead.
There is no guarantee it will perform worse if you do end up with a
function-call interface. Sure, it's likely, but (a) compilers continually
get better at optimizing, (b) CPUs get better every year at executing bad
code, and (c) you shouldn't worry about optimization until your program is
correct and you can prove there's a performance problem that merits writing
less-maintainable code.
Keep in mind that you need to keep the get/set functions + the actual type
definition in a seperate file to get the encapsulation effect.
That means that no mainstream C compiler will be able to optimize those
function calls away
That doesn't mean they need to be in a separate .c file; see above.
(AFAIK neither GNU, nor MS, nor Borland can inline functions from other
files).
There do exist compilers that can optimize, including inlining, across
translation units. I don't know the status of the ones you list; ask Google
about "Whole-Program Optimization". My understanding is that's fairly rare
today; at best you get inter-procedural optimizations within a single
translation unit with most compilers. That argues for (today) sticking with
the latter encapsulation strategy I describe above, rather than the one
you're assuming, if you can show the latter causes performance problems.

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Jun 15 '07 #6
On Fri, 15 Jun 2007 13:06:01 +1200, Ian Collins wrote:
>copx wrote:
>If the type of "object" is incomplete, you could not write object->colour or
something like that, because accessing data of incomplete type is not
possible.
[...]
>So do you consider that proper C style?

Yes, and it's a very common idiom (have you ever manipulated a FILE
object?).
Unfortunately you frequently see generous 'un-encapsulation' in C
code. Structs are defined completely in the header file but only
pointers to functions are used in the function declarations (other
'private' elements (defines, macros, enums) are also unnecessarily
placed into the header). Many programmers seem to be unaware of gratis
encapsulation.
>Personally, I am not sure what to think of this. It seems to scream "Why do
you not use C++ already?!".
Nothing to do with C++, unless you are using a similar idiom with opaque
types, C++ classes lay their innards bare for all to see.
but not for all to access. Encapsulation is independent of language
and paradigm (it's not an original OO feature).

--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Jun 15 '07 #7

"Eric Sosman" <es*****@acm-dot-org.invalidschr ieb im Newsbeitrag
news:w6******** *************** *******@comcast .com...
[snipping example of sensible use]
This freedom isn't always important, and it's silly to be a
slave to encapsulation orthodoxy for no purpose. But it can also
be a potent tool, capable of simplifying designs and easing
debugging. The trick is to know when to indulge and when to
abstain.
Yes, I think that is probably the way to go.

[snip]
Jun 15 '07 #8
On Fri, 15 Jun 2007 01:50:34 +0100, Ben Bacarisse
<be********@bsb .me.ukwrote:
>"copx" <co**@gazeta.pl writes:
>I have recently read "Everything you ever wanted to know about C types" by
Peter Seebach (1), and learned about incomplete types. Now, I realise the
value of encapsulation, but I wonder whether it is proper C style to use
that much of it. By using incomplete types you end up with something like
this:

object_set_col our(object, RED);
colour = object_get_colo ur(object);

If you end up with this you don't really *have* any encapsulation.
All you've done invent new syntax for:
>instead of:

object->colour = RED;
colour = object->colour;

as you have spotted.
Not quite. With the first variation, you don't need access to the
components of object, or even to know their names or other properties.
>
Incomplete types are at their most useful when the interface you have
to define is small compared to the complexity (or probable
variability) of the implementation that is hidden behind it.
--
Al Balmer
Sun City, AZ
Jun 15 '07 #9
Al Balmer <al******@att.n etwrites:
On Fri, 15 Jun 2007 01:50:34 +0100, Ben Bacarisse
<be********@bsb .me.ukwrote:
>>"copx" <co**@gazeta.pl writes:
>>I have recently read "Everything you ever wanted to know about C types" by
Peter Seebach (1), and learned about incomplete types. Now, I realise the
value of encapsulation, but I wonder whether it is proper C style to use
that much of it. By using incomplete types you end up with something like
this:

object_set_co lour(object, RED);
colour = object_get_colo ur(object);

If you end up with this you don't really *have* any encapsulation.
All you've done invent new syntax for:
>>instead of:

object->colour = RED;
colour = object->colour;

as you have spotted.

Not quite. With the first variation, you don't need access to the
components of object, or even to know their names or other
properties.
Good point. And you also have a place to put checks and debug tests,
which can be quite handy. But you are still not getting the most from
the *idea* of encapsulation if this is what most of the interface
looks like.

--
Ben.
Jun 15 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2298
by: .pd. | last post by:
If I have a control that adds itself to its container, does that break encapsulation? Is it a bad thing? Here's what I mean: public class fred { public barny b; public fred() {
3
1788
by: K.K. | last post by:
Consider the following code: >>>>>>>>>>> // Define an empty class public class ZorgleCollection : Dictionary<string, Zorgle> { } // Somewhere outside ZorgleCollection:
3
41531
by: enchantingdb | last post by:
I have an exam tomorrow that covers the perceived advantages and disadvantages of object oriented programming, in particular polymorphism, inheritance and encapsulation. I know the advantages but am not clear on the disadvantages. I have had a look on the Web and in newsgroups but couldn't find much. As time is running out, I thought I would post here and hope that someone would reply. Thanks Rob
6
2167
by: William H. Burling | last post by:
I am not sure I understand encapsulation. I thought that one of the objectives in OOPs is to hide data structures from other objects so that they did not have to know how to unpack them. However, in some instances, it seems that passing a data structure greatly reduces the number of accesses one might have to make between objects. Ie: a simple database might present an "offering" (which is
5
1669
by: jmsantoss | last post by:
Hi, This is a design question. I have a class named "DataBuffer" that stores some data. After "DataBuffer" is created it can not be modified. All the methods of "DataBuffer" are const as data can not be modified after it was created. Up to here everything is fine. The problem is when I want to get clever with data storage. My program has an array of "DataBuffers" that gets pre-allocated. If I want to use that memory instead of...
47
3333
by: Roger Lakner | last post by:
I often see operator implemented something like this: class Foo { ... }; class FooList { public: const Foo& operator (unsigned index) const {return array;}; Foo& operator (unsigned index) {return
32
4200
by: bluejack | last post by:
Ahoy: For as long as I've been using C, I've vacillated on the optimal degree of encapsulation in my designs. At a minimum, I aggregate data and code that operate on that data into classlike files; but now and then I go on an opaque type joyride, and create minimalist header files that define very clean interfaces. The problem with that is that it prevents some optimizations:
2
7628
by: subramanian100in | last post by:
Is my following understanding correct ? Data abstraction means providing the interface - that is, the set of functions that can be called by the user of a class. Information hiding means mentioning the class members(functions, typedefs, data) under the access control labels : public, protected, private. Encapsulation means providing the implementation of class member
0
8411
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8323
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8838
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8739
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8613
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7351
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5638
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4173
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
1969
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.