Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| Subject | Re: Generic read/write function - casting vs union |
|---|---|
| Newsgroups | comp.lang.c |
| References | <ns08ge$o5v$1@dont-email.me> <ns0hps$mc6$1@dont-email.me> <ns0jt5$tfh$1@dont-email.me> |
| From | Richard Damon <Richard@Damon-Family.org> |
| Message-ID | <PEbFz.591$qR5.172@fx21.iad> (permalink) |
| Organization | Forte - www.forteinc.com |
| Date | 2016-09-23 11:13 -0400 |
On 9/22/16 8:46 AM, Noob wrote:
> As you allude to, there is some context between PROLOG and EPILOG.
>
> PROLOG does several "setup" operations, which must be "torn down"
> in the reverse order in EPILOG, with proper error-handling, meaning
> we cannot tear down a resource that has not been set up.
>
> PROLOG:
> alloc #1
> if (failure) goto L1;
> alloc #2
> if (failure) goto L2;
> alloc #3
> if (failure) goto L3;
>
> EPILOG:
> tear_down(#3);
> L3:
> tear_down(#2);
> L2:
> tear_down(#1);
> L1:
> return err;
>
> Also I'm not a fan of separating PROLOG and EPILOG, because they
> are obviously closely related, and it doesn't make sense to call
> one without the other. But it's interesting to have other points
> of view.
>
> Regards.
>
One alternative, if you want to avoid the cast are willing to have
prolog and epilog be seperate functions would be something like
struct resources {
/* Info about resources here */
};
static int prolog(void* dev, struct resources* res) {
alloc #1
if (failure) return 1;
alloc #2
if (failure) return 2;
alloc #3
if (failure) return 3;
return 0;
}
static int epilog(int err, void* dev, struct resources* res) {
switch(err) {
/* All cases intentionally fall through */
case 0:
tear_down #3
case 3:
tear_down #2
case 2:
tear_down #1
case 1:
}
}
void read(void* dev, void* buf, int len) {
struct resources res;
int err = prolog(dev, &res);
if(err == 0) do read
epilog(err, dev, &res);
}
prolog and epilog are made static functions so they are only accessible
in that file, as other code should not be accessing them.
Having made them into separate functions, if some other operation (maybe
a 'seek', or 'rewind' or 'update' operation) is added, it can use the
same prolog/epilog operations to implement it, and that operation can
just be added to the API. You don't need to touch the read or write
routines. Having your 'access' routine (maybe better called something
like doReadOrWrite, which should also be a static function) says that if
some other operation needs any other parameters to define it, the
signature of the common function needs to be changed, and read and write
modified to pass some dummy value for that parameter. You also have, as
you commented, the need for something like the cast to take away the
const for the write routine.
Anticipating that there may be information about the resources that
needs to be passed, from prolog to operation and epilog, I have added a
resources struct for that data. If we wanted, we could even include the
err flag in there, but I think being explicit about that is good, and
makes it easier for prolog to signal the state.
An alternative to casting away the const is to pass two pointers to
access, one a void *, and one a void const*, read passing a NULL to the
void const* (which isn't used by the read operation) and write passing a
NULL to the void * (which isn't used by the write operation).
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-22 11:33 +0200
Re: Generic read/write function - casting vs union Richard Heathfield <rjh@cpax.org.uk> - 2016-09-22 11:07 +0100
Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-22 12:36 +0200
Re: Generic read/write function - casting vs union Richard Heathfield <rjh@cpax.org.uk> - 2016-09-22 14:07 +0100
Re: Generic read/write function - casting vs union Keith Thompson <kst-u@mib.org> - 2016-09-22 11:48 -0700
Re: Generic read/write function - casting vs union raltbos@xs4all.nl (Richard Bos) - 2016-09-23 19:42 +0000
Re: Generic read/write function - casting vs union BartC <bc@freeuk.com> - 2016-09-22 13:11 +0100
Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-22 14:46 +0200
Re: Generic read/write function - casting vs union David Brown <david.brown@hesbynett.no> - 2016-09-22 15:10 +0200
Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-22 15:36 +0200
Re: Generic read/write function - casting vs union Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-22 19:28 -0700
Re: Generic read/write function - casting vs union David Brown <david.brown@hesbynett.no> - 2016-09-23 09:59 +0200
Re: Generic read/write function - casting vs union Barry Schwarz <schwarzb@dqel.com> - 2016-09-22 20:11 -0700
Re: Generic read/write function - casting vs union Richard Damon <Richard@Damon-Family.org> - 2016-09-23 11:13 -0400
Re: Generic read/write function - casting vs union Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-22 08:35 -0700
Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-25 23:17 +0200
Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-26 14:54 +0200
Re: Generic read/write function - casting vs union boon <root@localhost.localdomain> - 2016-09-26 19:47 +0200
Re: Generic read/write function - casting vs union Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-26 19:23 +0100
Re: Generic read/write function - casting vs union Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-27 13:10 -0700
Re: Generic read/write function - casting vs union David Thompson <dave.thompson2@verizon.net> - 2016-10-16 18:08 -0400
Re: Generic read/write function - casting vs union Anton Shepelev <anton.txt@gmail.com> - 2016-10-17 23:40 +0300
Re: Generic read/write function - casting vs union albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2016-12-11 15:20 +0100
Re: Generic read/write function - casting vs union supercat@casperkitty.com - 2016-12-11 09:38 -0800
csiph-web