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. 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)
{
....
}
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.
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.
"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
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/
"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;
"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/
"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.
"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++ This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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
|
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;
?
|
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.......
|
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.
|
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)
| |
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";
|
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)
{
|
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:
|
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;
|
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
|
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,...
| |
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...
|
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...
|
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...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
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
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
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...
| |