473,781 Members | 2,280 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

style question

When I write a medium to large sized C application I tend to create
structures first, then makeStruct and freeStruct functions that dynamically
allocate/free the struct and then I create a bunch of functions that operate
on the struct. Example:

typedef struct ccHashTab
{
.....
} ccHashTab;

ccHashTab * ccMakeHash(unsi gned int size, hash h, comp c);
void ccFreeHashTab(c cHashTab *table);
void *ccHashFindSym( ccHashTab *table, void *symbol);
......

This is a bit the object-oriented way, because I never touch the struct
members directly, only inside the hash functions.
Now I'm wondering if this is a style that other C programmers use in their
work or if they're using something different. I just want to know some
opinions, maybe I'll get some new insights.
Nov 13 '05 #1
23 2751

"Serve La" <ik@veranderhet al.com> wrote in message
news:bj******** **@news3.tilbu1 .nb.home.nl...
When I write a medium to large sized C application I tend to create
structures first, then makeStruct and freeStruct functions that dynamically allocate/free the struct and then I create a bunch of functions that operate on the struct. Example:

typedef struct ccHashTab
{
....
} ccHashTab;

ccHashTab * ccMakeHash(unsi gned int size, hash h, comp c);
void ccFreeHashTab(c cHashTab *table);
void *ccHashFindSym( ccHashTab *table, void *symbol);
.....

This is a bit the object-oriented way, because I never touch the struct
members directly, only inside the hash functions.
Now I'm wondering if this is a style that other C programmers use in their
work or if they're using something different. I just want to know some
opinions, maybe I'll get some new insights.


to hide the details of struct ccHashTab and make it a bit more OO I would do
something like the following(espec ially if you don't access ccHashTab
members directly)

in hashtab.h

typedef struct ccHashTab * ccHashTabRef;

ccHashTabRef ccMakeHash(unsi gned int size, hash h, comp c);
void ccFreeHashTab(c cHashTabRef table);
void *ccHashFindSym( ccHashTabRef table, void *symbol);

in hashtab.c
#include "hashtab.h"
struct ccHashTab
{
....
}

ccHashTabRef ccMakeHash(unsi gned int size, hash h, comp c)
{
....
}
void ccFreeHashTab(c cHashTabRef table)
{
....
}
void *ccHashFindSym( ccHashTabRef table, void *symbol)
{
....
}
Nov 13 '05 #2
Serve La wrote:
When I write a medium to large sized C application I tend to create
structures first, then makeStruct and freeStruct functions that dynamically
allocate/free the struct and then I create a bunch of functions that operate
on the struct. Example:
typedef struct ccHashTab {
// ...
} ccHashTab;

ccHashTab ccHashTab_creat e(unsigned int size, hash h, comp c);
void ccHashTab_destr oy(const ccHashTab* pTable);
void* ccHashTab_find( ccHashTab* pTable, void* pSymbol);
.....

This is a bit the object-oriented way
because I never touch the struct members directly,
only inside the hash functions.
Now I'm wondering if this is a style
that other C programmers use in their work
or if they're using something different.
I just want to know some opinions, maybe I'll get some new insights.


Try to avoid functions that return a pointer to memory
allocated from the free store.

Nov 13 '05 #3
Serve La <ik@veranderhet al.com> wrote:
When I write a medium to large sized C application I tend to create
structures first, then makeStruct and freeStruct functions that dynamically
allocate/free the struct and then I create a bunch of functions that operate
on the struct. Example:

typedef struct ccHashTab
{
....
} ccHashTab;

ccHashTab * ccMakeHash(unsi gned int size, hash h, comp c);
void ccFreeHashTab(c cHashTab *table);
void *ccHashFindSym( ccHashTab *table, void *symbol);
.....

This is a bit the object-oriented way, because I never touch the struct
members directly, only inside the hash functions.
Now I'm wondering if this is a style that other C programmers use in their
work or if they're using something different. I just want to know some
opinions, maybe I'll get some new insights.


Yeah, that's fairly common. If you want to stop the user from accessing
the internals of the structs, you can declare them incompletely in the
header file:

typedef struct ccHashTab ccHashTab;

then fully define the struct in the .c file that implements the hash
table:

struct ccHashTab {
...
}

It's not a good idea to use a typedef to hide the fact that it's a
pointer (which you haven't done anyway, but one of the other replies in
this thread does) - if the user knows it's a pointer they know they can
safely do things like assign it to a void * and back again, and compare
the constructor function return value against NULL to check for errors.

- Kevin.

Nov 13 '05 #4

"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote in message
news:3F******** ******@jpl.nasa .gov...
Try to avoid functions that return a pointer to memory
allocated from the free store.


That is IMO only good for simple structs where all data is known at
compile-time. If a struct gets complicated I don't want to put the burden on
allocating the struct on a client programmer. Chances are she forgets a NULL
check somewhere or does it wrong.
What I do now is create an extra function ccConstructHash Tab that performs
the role of a constructor. This function doesn't care if the pointer is
pointing to dynamic memory or not.
But most of my structs are too complicated for static storage
Nov 13 '05 #5
Serve La wrote:
E. Robert Tisdale wrote:
Try to avoid functions that return a pointer to memory
allocated from the free store.


That is, IMO, only good for simple structs
where all data is known at compile-time.
If a struct gets complicated,
I don't want to put the burden on allocating the struct
on a client programmer.
Chances are she forgets a NULL check somewhere or does it wrong.
What I do now is create an extra function ccConstructHash Tab
that performs the role of a constructor. This function doesn't care
if the pointer is pointing to dynamic memory or not.
But most of my structs are too complicated for static storage.


You are confused. A pseudo constructor like

ccHashTab ccHashTab_creat e(unsigned int size, hash h, comp c);

places *no* "burden" on the application program.
It works well no matter how complicated the data structure.

People have been doing this sort of thing for a very long time.
Take a look, for example, at The ANSI C Numerical Class Library

http://www.netwood.net/~edwin/svmtl/

It allows you to construct vector and matrix objects from either
automatic or free storage. You might also look at
The GNU Scientific Library (GSL)

http://sources.redhat.com/gsl/

Nov 13 '05 #6

"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote in message
news:3F******** ******@jpl.nasa .gov...
ccHashTab ccHashTab_creat e(unsigned int size, hash h, comp c);

places *no* "burden" on the application program.
It works well no matter how complicated the data structure.

People have been doing this sort of thing for a very long time.
Take a look, for example, at The ANSI C Numerical Class Library

http://www.netwood.net/~edwin/svmtl/

It allows you to construct vector and matrix objects from either
automatic or free storage. You might also look at
The GNU Scientific Library (GSL)

http://sources.redhat.com/gsl/


I can't unzip those, could you give an example?

Here's a fairly complicated struct that I now allocate in a function:

typedef struct Inner
{
ITypeInfo *info;
TYPEATTR *attr;
BSTR name;
int index;
} Inner;

typedef struct SomeStruct
{
GUID libid;
ITypeLib *lib;
Inner *info;
UINT ntypeinfo;
BSTR filename;
BSTR helpstring;
BSTR helpfilename;
UINT currentiter;
} SomeStruct;
Nov 13 '05 #7
"Serve La" <ik@veranderhet al.com> wrote:
When I write a medium to large sized C application I tend to create
structures first, then makeStruct and freeStruct functions that dynamically
allocate/free the struct and then I create a bunch of functions that operate
on the struct. Example:

typedef struct ccHashTab
{
....
} ccHashTab;
This typedef is unnecessary and doesn't really do anything useful,
except confuse C++ people (in C++ struct ___ doesn't create a new name
space, the "struct" can be dropped.)
ccHashTab * ccMakeHash(unsi gned int size, hash h, comp c);
void ccFreeHashTab(c cHashTab *table);
void *ccHashFindSym( ccHashTab *table, void *symbol);
.....
I do it this way:

/* constructor/destructor */
struct ccHashTab * newCcHash (unsigned int size, int (* keyFn)(void
*));
int destroyCcHash (struct ccHashTab *table);

int clearCcHash (struct ccHashTab *table);
int iterateCcHash (struct ccHashTab *table,
int (* cb) (void * ctx, void * entry), void * ctx);
int insertCcHash (struct ccHashTab *table, void * entry);
int deleteCcHash (struct ccHashTab *table, void * entry);
void * findCcHash (struct ccHashTab *table, void * entry);
/* and other "methods" */

is put in hash.h, and the struct ccHashTab definition is only in the
hash module. Knowing that its a pointer to a struct doesn't really
ruin its opaqueness, if you don't know the structure contents.
However, it makes it clear that you cannot copy it without a copy
method.

One of the things that's always bothered me is that I cannot put
"const" on the table declaration in the findCcHash function. The
reason is that you are returning a pointer that table is pointing to,
and thus the compiler cannot figure out whether or not you might
modify its contents.
This is a bit the object-oriented way, because I never touch the struct
members directly, only inside the hash functions.


Of course the burning question, then is, why not use C++ instead of C
then?

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 13 '05 #8
"E. Robert Tisdale" wrote:
Serve La wrote:
When I write a medium to large sized C application I tend to
create structures first, then makeStruct and freeStruct
functions that dynamically allocate/free the struct and then
I create a bunch of functions that operate on the struct.
Example:

typedef struct ccHashTab {
// ...
} ccHashTab;

ccHashTab ccHashTab_creat e(unsigned int size, hash h, comp c);
void ccHashTab_destr oy(const ccHashTab* pTable);
void* ccHashTab_find( ccHashTab* pTable, void* pSymbol);
.....

This is a bit the object-oriented way because I never touch
the struct members directly, only inside the hash functions.
Now I'm wondering if this is a style that other C programmers
use in their work or if they're using something different.
I just want to know some opinions, maybe I'll get some new
insights.


Try to avoid functions that return a pointer to memory
allocated from the free store.


This is nonsense advice, especially in this context.

To the OP: You need to evaluate the advice given in c.l.c,
dependant on the advisor. In general advice from ERT is likely to
be valueless, off-topic, and wrong.

Your general approach is worthwhile. It is also advisable to
find ways to hide the actual construction of these entities, so
that you are free to alter the implementation without affecting
the usage. For an example in my style see:

<http://cbfalconer.home .att.net/download/hashlib.zip>

--
Replies should be to the newsgroup
Chuck Falconer, on vacation.
Nov 13 '05 #9

"Paul Hsieh" <qe*@pobox.co m> wrote in message
news:79******** *************** ***@posting.goo gle.com...
This is a bit the object-oriented way, because I never touch the struct
members directly, only inside the hash functions.


Of course the burning question, then is, why not use C++ instead of C
then?


Huh?
Because OO is not bound to C++
Nov 13 '05 #10

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

Similar topics

12
3833
by: David MacQuigg | last post by:
I have what looks like a bug trying to generate new style classes with a factory function. class Animal(object): pass class Mammal(Animal): pass def newAnimal(bases=(Animal,), dict={}): class C(object): pass C.__bases__ = bases dict = 0
15
1734
by: Christopher Benson-Manica | last post by:
If you had an unsigned int that needed to be cast to a const myClass*, would you use const myClass* a=reinterpret_cast<const myClass*>(my_val); or const myClass* a=(const myClass*)myVal; ?
33
2509
by: amerar | last post by:
Hi All, I can make a page using a style sheet, no problem there. However, if I make an email and send it out to my list, Yahoo & Hotmail totally ignore the style tags. It looks fine in Netscape though..... Question: I've tried linking & embedding the style tags with no luck. How can I use them inline? I've read that inline style sheets is the way to go if you want them to work in most email clients.......
1
1410
by: amerar | last post by:
Hi All, I posted a question about style sheets, and why certain email clients were ignoring them. Someone suggested placing them inline. I did this and get better results, but not what I wanted. The page still appears properly, and it shows in Netscape Messenger just fine, but on Hotmail and Yahoo, each <DIV> tag does not appear where it is supposed to appear.
4
6598
by: KvS | last post by:
Hi all, I'm pretty new to (wx)Python so plz. don't shoot me if I've missed something obvious ;). I have a panel inside a frame, on which a Button and a StaticText is placed: self.panel = wx.Panel(self,-1) self.button = wx.Button(self.panel,-1,"Klikkerdeklik") self.button.SetPosition((200,40)) self.Bind(wx.EVT_BUTTON, self.VeranderLabel, self.button)
83
15626
by: rahul8143 | last post by:
hello, what is difference between sizeof("abcd") and strlen("abcd")? why both functions gives different output when applied to same string "abcd". I tried following example for that. #include <stdio.h> #include <string.h> void main() { char *str1="abcd";
39
2221
by: jamilur_rahman | last post by:
What is the BIG difference between checking the "if(expression)" in A and B ? I'm used to with style A, "if(0==a)", but my peer reviewer likes style B, how can I defend myself to stay with style A ? style A: .... .... int a = 1; if(0==a) {
18
2125
by: pocmatos | last post by:
Hi all, While I was programming 5 minutes ago a recurring issue came up and this time I'd like to hear some opinions on style. Although they are usually personal I do think that in this case as also to do with making the code easier to read. Imagine a function returning void (for example) and it's body is a big if with lots of special cases:
3
1957
Claus Mygind
by: Claus Mygind | last post by:
I want to move some style setting into a javaScript function so I can make them variable but I get "invalid assignment left-hand side" error? see my question at the bottom of this message. It works fine when I stream it out in my html page like this: <DIV ID="popSearch" STYLE=" position:absolute; visibility:hidden;
6
1994
by: MatthewS | last post by:
I've seen the question raised several times here, but apparently never answered. Since PyInstance_Check returns False for new-style class instances, is there a standard procedure for testing this using the C- Api? I would greatly appreciate some help with this. /Matthew
0
9474
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
10306
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
9931
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...
1
7485
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5373
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...
0
5504
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4037
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3632
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2869
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.