Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #22497 > unrolled thread

Design decisions

Started byjacob navia <jacob@spamsink.net>
First post2012-06-21 22:19 +0200
Last post2012-06-25 00:27 -0600
Articles 15 on this page of 35 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  Design decisions jacob navia <jacob@spamsink.net> - 2012-06-21 22:19 +0200
    Re: Design decisions Andrew Cooper <amc96@cam.ac.uk> - 2012-06-21 21:43 +0100
    Re: Design decisions "BartC" <bc@freeuk.com> - 2012-06-21 22:02 +0100
      Re: Design decisions Gareth Owen <gwowen@gmail.com> - 2012-06-21 23:23 +0100
        Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-22 09:12 +0200
          Re: Design decisions Ian Collins <ian-news@hotmail.com> - 2012-06-22 19:44 +1200
            Re: Design decisions "Joe." <antelope3@news.net> - 2012-06-25 00:32 -0600
          Re: Design decisions gwowen <gwowen@gmail.com> - 2012-06-22 01:00 -0700
            Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-22 10:08 +0200
              Re: Design decisions Gareth Owen <gwowen@gmail.com> - 2012-06-22 17:18 +0100
                Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-22 18:27 +0200
                  Re: Design decisions Ian Collins <ian-news@hotmail.com> - 2012-06-23 08:44 +1200
                    Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-22 23:58 +0200
                      Re: Design decisions Ian Collins <ian-news@hotmail.com> - 2012-06-23 10:21 +1200
                        Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-23 02:13 +0200
                          Re: Design decisions Ian Collins <ian-news@hotmail.com> - 2012-06-23 12:59 +1200
                            Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-23 11:03 +0200
                              Re: Design decisions Ian Collins <ian-news@hotmail.com> - 2012-06-23 21:52 +1200
                                Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-23 12:32 +0200
                                Re: Design decisions Gareth Owen <gwowen@gmail.com> - 2012-06-23 13:54 +0100
              Re: Design decisions "Joe." <antelope3@news.net> - 2012-06-25 00:36 -0600
            Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-22 10:42 +0200
              Re: Design decisions Gareth Owen <gwowen@gmail.com> - 2012-06-22 17:18 +0100
              Re: Design decisions jacob navia <jacob@spamsink.net> - 2012-06-24 18:32 +0200
      Re: Design decisions James Kuyper <jameskuyper@verizon.net> - 2012-06-21 18:43 -0400
        Re: Design decisions "Joe." <antelope3@news.net> - 2012-06-25 00:40 -0600
      Re: Design decisions "Joe." <antelope3@news.net> - 2012-06-25 00:28 -0600
    Re: Design decisions "io_x" <a@b.c.invalid> - 2012-06-22 08:35 +0200
    Re: Design decisions Neil Cerutti <neilc@norwich.edu> - 2012-06-22 12:40 +0000
      Re: Design decisions gwowen <gwowen@gmail.com> - 2012-06-22 06:01 -0700
        Re: Design decisions Neil Cerutti <neilc@norwich.edu> - 2012-06-22 14:26 +0000
      Re: Design decisions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-22 14:01 +0100
      Re: Design decisions David Resnick <lndresnick@gmail.com> - 2012-06-22 06:13 -0700
    Re: Design decisions Jens Gustedt <jens.gustedt@loria.fr> - 2012-06-22 19:05 +0200
    Re: Design decisions "Joe." <antelope3@news.net> - 2012-06-25 00:27 -0600

Page 2 of 2 — ← Prev page 1 [2]


#22647

From"Joe." <antelope3@news.net>
Date2012-06-25 00:36 -0600
Message-ID<js90ib$6g6$3@speranza.aioe.org>
In reply to#22524
"jacob navia" <jacob@spamsink.net> wrote in message 
news:js1968$26c$1@speranza.aioe.org...
> Le 22/06/12 10:00, gwowen a écrit :
>> On Jun 22, 8:12 am, jacob navia <ja...@spamsink.net> wrote:
>>> If you use pooled memory access you can release the memory pool
>>> associated with the current error, and you have the exact mechanism
>>> of the C++ exceptions combined with cleanup by stack unwinding in
>>> a much cheaper and efficient way.
>>
>> Really? Do you really believe that? What about resources that are not
>> memory - mutex/critical sections, network connections, open ports,
>> file descriptors.
>>
>> How would I use your error handler to do this:
>>
>
> [snip code]
>
>
> Very easy. Just use a pushdown stack. Each time you acquire a
> mutex lock you push it in  the stack, each time you release it you pop it.
>
> If an exception occurs, you pop the whole mutex stack. This would
> require just a few lines more of code.
>

"So much" discussion for .... ah, my bad.. y'all are just learning how to 
program. And I say I'm intuitive. Code-on, grasshoppers.

- They call it "freedom", but rape is legal. (unknown). 

[toc] | [prev] | [next] | [standalone]


#22526

Fromjacob navia <jacob@spamsink.net>
Date2012-06-22 10:42 +0200
Message-ID<js1b5j$72h$1@speranza.aioe.org>
In reply to#22523
Le 22/06/12 10:00, gwowen a écrit :
>> I had this strategy but it is unworkable since you can't know in
>> >advance if a zero will appear in the data!
> But it might be desirable for a user to be able to specify such
> behaviour in his error handler.  For example, in signal processing its
> often useful to assume that the data-array is zero-padded-to-infinity,
> so I may use a C++ object like this:
>
> class zero_padded_array
> {
> private:
>   public std::vector<double> v_;
>
> public:
>   const double& at(size_t idx) const {
>     if(idx >= v_.size()){
>        return 0.0;
>     } else {
>        return v_[idx];
>     }
>   }
>   // Rest of interface.
> }
>
> Can I use an error handler to handle out-of-bounds access in you
> library to get that behaviour?
>

Yes.

Method 1: Modify a vector's VTable (long)

You write a new "GetElement" function:


typedef void *(*fnPtr)(Vector *,size_t);

fnPtr oldGetElementFunction;

static double error_return = 0.0;

static double *MyGetElement(doubleVector *v,size_t idx)
{
     if (idx >= iVector.Size(v))
         return &error_return;
     // Call the original function;
     return oldGetElementFunction(v,idx);
}

Now, when you want to create an infinite vector you write:

Vector *CreateExtensibleVector(size_t realSize)
{
     VectorInterface *intf;
     Vector *result = idoubleVector.Create(20); // 20 real elements
     // Save the original function to be used later
     oldGetElementFunction = result->VTable->GetElement;
     intf = malloc(sizeof(VectorInterface));
     memcpy(intf,result->VTable,sizeof(VectorInterface));
     result->VTable = intf;
     // Replace the GetElement in THIS vector
     result->VTable->GetElement = MyGetElement;
     result->Vtable->Finalize = MyFinalize;
     return result;
}

Instead of writing iVector.GetElement you use the macro:

#define iVector_GetElement(vector,idx)  \
          vector->VTable->GetElement(vector,idx);

That will work with normal vectors AND with extensible ones.
Note that the trivial new Finalize procedure is skipped. It just frees
the copied VTable allocated with malloc.

True, this approach is not as easy as the C++ one, but it has the
advantage of being much more flexible. You can subclass before
or after calling the original procedure, or you can bypass the
called procedure entirely.

Method 2: Shorter
Make ALL vectors extensible:
Vector *CreateExtensibleVector(size_t realSize)
{
     Vector *result = idoubleVector.Create(20); // 20 real elements
     // Save the original function to be used later
     oldGetElementFunction = result->VTable->GetElement;
     // Replace the GetElement in ALL vectors
     iVector.GetElement = MyGetElement;
     return result;
}
-----------------------------------------------------------------------------

Note that I haven't answered your original question:

 > Can I use an error handler to handle out-of-bounds access in you
 > library to get that behaviour?

I think you have a point here. I will modify the behavior of the
GetElement function so that it RETURNS the value returned by the
error handling procedure (if that procedure returns of course).

The return value of the error handling function should be a pointer
to a replacement data, or NULL or whatever.

Thanks for your input. Really appreciated.

jacob

[toc] | [prev] | [next] | [standalone]


#22544

FromGareth Owen <gwowen@gmail.com>
Date2012-06-22 17:18 +0100
Message-ID<87txy38gmx.fsf@gmail.com>
In reply to#22526
jacob navia <jacob@spamsink.net> writes:

>> Can I use an error handler to handle out-of-bounds access in you
>> library to get that behaviour?
>
> Yes. Method 1: Modify a vector's VTable (long) You write a new
> Yes. "GetElement" function:

Thank you.  Neat.

[toc] | [prev] | [next] | [standalone]


#22611

Fromjacob navia <jacob@spamsink.net>
Date2012-06-24 18:32 +0200
Message-ID<js7ffa$u5e$1@speranza.aioe.org>
In reply to#22526
Le 22/06/12 10:42, jacob navia a écrit :
> Note that the trivial new Finalize procedure is skipped. It just frees
> the copied VTable allocated with malloc.

This is no longer necessary. The standard Finalize procedure will
compare the VTable to the default value. If it is different, Finalize
wxill assume that it has been allocated and it will free it using the
Vector's allocator object.


One less thing to do.

[toc] | [prev] | [next] | [standalone]


#22509

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-06-21 18:43 -0400
Message-ID<4FE3A3AB.7080004@verizon.net>
In reply to#22501
On 06/21/2012 05:02 PM, BartC wrote:
> "jacob navia" <jacob@spamsink.net> wrote in message 
> news:jrvvlb$8k1$1@speranza.aioe.org...
>> In the new "templated" form of the containers library I have now that all 
>> data retrieving functions return the data directly:
>>
>> int (*GetElement)(intList *l,size_t idx);
>>
>> The problem is that it is not possible to return an error
>> with this configuration: Since the return value is an
>> int, any error code could be actually some data!!
>>
>> The solution is to return a pointer to the data and NULL
>> if there is an error, as the other functions of the library do.
> ...
>> What do you think?
> 
> How does C++ deal with it?

Of the C++ standard containers, only basic_string, array, deque, and
vector containers have a close equivalent of GetElement. The other
container types do not provide int-indexed access. The ones that do,
each have two GetElement equivalents. If Container is one of those
templates, then given the declaration:

	Container<T> container;

the expressions container[idx] and container.at(idx) both have the
semantics of *(container.begin()+n). If idx is out of range,
container[idx] has undefined behavior; container.at(idx) throws
std::out_of_range.

[toc] | [prev] | [next] | [standalone]


#22648

From"Joe." <antelope3@news.net>
Date2012-06-25 00:40 -0600
Message-ID<js90q2$6uh$1@speranza.aioe.org>
In reply to#22509
"James Kuyper" <jameskuyper@verizon.net> wrote in message 
news:4FE3A3AB.7080004@verizon.net...
> On 06/21/2012 05:02 PM, BartC wrote:
>> "jacob navia" <jacob@spamsink.net> wrote in message
>> news:jrvvlb$8k1$1@speranza.aioe.org...
>>> In the new "templated" form of the containers library I have now that 
>>> all
>>> data retrieving functions return the data directly:
>>>
>>> int (*GetElement)(intList *l,size_t idx);
>>>
>>> The problem is that it is not possible to return an error
>>> with this configuration: Since the return value is an
>>> int, any error code could be actually some data!!
>>>
>>> The solution is to return a pointer to the data and NULL
>>> if there is an error, as the other functions of the library do.
>> ...
>>> What do you think?
>>
>> How does C++ deal with it?
>
> Of the C++ standard containers, only basic_string, array, deque, and
> vector containers have a close equivalent of GetElement. The other
> container types do not provide int-indexed access. The ones that do,
> each have two GetElement equivalents. If Container is one of those
> templates, then given the declaration:
>
> Container<T> container;
>
> the expressions container[idx] and container.at(idx) both have the
> semantics of *(container.begin()+n). If idx is out of range,
> container[idx] has undefined behavior; container.at(idx) throws
> std::out_of_range.

Pfft. An "authority" on C++? Apparently you are milking the fact that you 
know a lot about a nothing, that nothing being C++? I've been programming in 
C# for 3 years and know it is superior to C++, or I may be lying. 

[toc] | [prev] | [next] | [standalone]


#22645

From"Joe." <antelope3@news.net>
Date2012-06-25 00:28 -0600
Message-ID<js90i8$6g6$1@speranza.aioe.org>
In reply to#22501
"BartC" <bc@freeuk.com> wrote in message news:js025k$hjm$1@dont-email.me...
> "jacob navia" <jacob@spamsink.net> wrote in message 
> news:jrvvlb$8k1$1@speranza.aioe.org...
>> In the new "templated" form of the containers library I have now that all 
>> data retrieving functions return the data directly:
>>
>> int (*GetElement)(intList *l,size_t idx);
>>
>> The problem is that it is not possible to return an error
>> with this configuration: Since the return value is an
>> int, any error code could be actually some data!!
>>
>> The solution is to return a pointer to the data and NULL
>> if there is an error, as the other functions of the library do.
> ...
>> What do you think?
>
> How does C++ deal with it?
>
> My feeling is that GetElement should be as simple and convenient to use as 
> possible, especially for the 99.999% of calls (and usually 100%) where 
> there is no error. Perhaps have two versions, one where any errors are 
> handled internally (either aborting, returning an agreed default value, or 
> whatever), and another which has full error returns for people who insist 
> on checking every single list access themselves.
>

He sucked you in? 

[toc] | [prev] | [next] | [standalone]


#22515

From"io_x" <a@b.c.invalid>
Date2012-06-22 08:35 +0200
Message-ID<4fe410dd$0$1389$4fafbaef@reader1.news.tin.it>
In reply to#22497
"jacob navia" <jacob@spamsink.net> ha scritto nel messaggio
news:jrvvlb$8k1$1@speranza.aioe.org...
> In the new "templated" form of the containers library I have now that all data
> retrieving functions return the data directly:
>
> int (*GetElement)(intList *l,size_t idx);
>
> The problem is that it is not possible to return an error
> with this configuration: Since the return value is an
> int, any error code could be actually some data!!

in how i see it: -1 in return for one function means error
if -1 is a sensible data for return to caller; use:
u32  (*GetElement)(i32*  result, intList *l,size_t idx);

i32  result;
if(getelemte(&result etc)==-1)  error()

separate error code from data...

it will good every world function follow these laws
but even my not follow them... now too, i don't know why...

desclaimer: there are many experts here, i'm just a beginner
i don't know what error follow from my vision
of software...

[toc] | [prev] | [next] | [standalone]


#22536

FromNeil Cerutti <neilc@norwich.edu>
Date2012-06-22 12:40 +0000
Message-ID<a4j7eoFhdmU2@mid.individual.net>
In reply to#22497
On 2012-06-21, jacob navia <jacob@spamsink.net> wrote:
> In the new "templated" form of the containers library I have
> now that all data retrieving functions return the data
> directly:
>
> int (*GetElement)(intList *l,size_t idx);
> ...
> What do you think?

Taking a step back, why not just return garbage for bad indices?
That seems more like what a C programmer would expect.

-- 
Neil Cerutti

[toc] | [prev] | [next] | [standalone]


#22537

Fromgwowen <gwowen@gmail.com>
Date2012-06-22 06:01 -0700
Message-ID<dae11736-7a0c-4e86-9c91-85a8e5cd4a77@8g2000vbu.googlegroups.com>
In reply to#22536
On Jun 22, 1:40 pm, Neil Cerutti <ne...@norwich.edu> wrote:
> On 2012-06-21, jacob navia <ja...@spamsink.net> wrote:
>
> > ...
> > What do you think?
>
> Taking a step back, why not just return garbage for bad indices?
> That seems more like what a C programmer would expect.

Certainly "undefined behaviour", rather than returning garbage is the
most C-like thing to do.  It "works" for arrays.

[toc] | [prev] | [next] | [standalone]


#22542

FromNeil Cerutti <neilc@norwich.edu>
Date2012-06-22 14:26 +0000
Message-ID<a4jdlgF7rrU1@mid.individual.net>
In reply to#22537
On 2012-06-22, gwowen <gwowen@gmail.com> wrote:
> On Jun 22, 1:40?pm, Neil Cerutti <ne...@norwich.edu> wrote:
>> On 2012-06-21, jacob navia <ja...@spamsink.net> wrote:
>>
>> > ...
>> > What do you think?
>>
>> Taking a step back, why not just return garbage for bad indices?
>> That seems more like what a C programmer would expect.
>
> Certainly "undefined behaviour", rather than returning garbage
> is the most C-like thing to do.  It "works" for arrays.

Returning garbage invokes undefined behavior, surely.

-- 
Neil Cerutti
  "This room is an illusion and is a trap devisut by Satan.  Go
ahead and dauntlessly!  Make rapid progres!"
  --Ghosts 'n Goblins

[toc] | [prev] | [next] | [standalone]


#22538

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-06-22 14:01 +0100
Message-ID<0.10fc8e4f7848498983cc.20120622140152BST.87lijfo5z3.fsf@bsb.me.uk>
In reply to#22536
Neil Cerutti <neilc@norwich.edu> writes:

> On 2012-06-21, jacob navia <jacob@spamsink.net> wrote:
>> In the new "templated" form of the containers library I have
>> now that all data retrieving functions return the data
>> directly:
>>
>> int (*GetElement)(intList *l,size_t idx);
>> ...
>> What do you think?
>
> Taking a step back, why not just return garbage for bad indices?
> That seems more like what a C programmer would expect.

In some contexts, that's a good solution.  I remember implementing a
simple scripting language that had typed containers.  The 'get' and
'put' operations acted on pointers, but 'get' never returned a NULL
pointer.  Every container always had a spare element, a pointer which
was returned by get for out-of-bounds indexes, and whose value would be
used for dereferenced out-of-bounds accesses.

The case is more murky for a C container API, but since Jacob also
provides the generic (untyped) interface, I think returning junk (zero?)
could be justified.  Programs that need to know every error condition
can use the full interface.

Jacob might also want to consider having a dummy element.  The most
efficient plan would probably be to have a single dummy element for each
size (properly aligned for all accesses of course).  An erroneous lookup
would return this pointer rather than NULL.  It could be tested for,
just like, NULL, but it would be valid to dereference it.  Such a scheme
can simplify things a bit, but I'm not familiar enough with the existing
API to be sure.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#22540

FromDavid Resnick <lndresnick@gmail.com>
Date2012-06-22 06:13 -0700
Message-ID<eb06e25a-7b60-4814-995a-7b40826e861e@googlegroups.com>
In reply to#22536
On Friday, June 22, 2012 8:40:56 AM UTC-4, Neil Cerutti wrote:
> Taking a step back, why not just return garbage for bad indices?
> That seems more like what a C programmer would expect.

Not even that bad advice to declare it "undefined" to used an out of bounds index.  Bear in mind that you are only checking one of the two parameters anyway -- passing in an invalid pointer to an intList itself would also be bad and (unless NULL is passed) be not readily subject to validation.  Not that I'm against bounds checking in the library, just not totally clear it needs to be the libraries problem.

For ints, you could always go the strtol route, namely return a value
that might be good or bad(e.g. LONG_MAX) on specified errors and set
errno.  Users would have to check errno on the sentinel return.  errno mechanism isn't so great, but, well, there you go, and it avoids cluttering up your interface with a pointer argument to use to return your value/error status...

That said, my personal inclination if I wanted to use C with Templates would be to use a C++ compiler and specify that a restricted set of features is desired, i.e., in this case, Templates (yes, yes, with the caveats that C++ isn't quite a superset of C).  It would be nice if such restrictions or policies could be enforced at the compiler level, mind you, or before you can say multiple inheritance other features you may or many not desire to allow would be in use..

[toc] | [prev] | [next] | [standalone]


#22547

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-06-22 19:05 +0200
Message-ID<4FE4A5BF.5080509@loria.fr>
In reply to#22497
Hello,

Am 21.06.2012 22:19, schrieb jacob navia:
> In the new "templated" form of the containers library I have now that
> all data retrieving functions return the data directly:
> 
> int (*GetElement)(intList *l,size_t idx);
> 
> The problem is that it is not possible to return an error
> with this configuration: Since the return value is an
> int, any error code could be actually some data!!
> 
> The solution is to return a pointer to the data and NULL
> if there is an error, as the other functions of the library do.
> 
> But this doesn't look great with the syntax viewed from the
> user's side:
> 
> Instead of:
>     int m = iintList.GetElement(mylist,23);
> you should write:
>     int m = *iintList.GetElement(myList,23);
> 
> risking a core dump if there is a NULL return.
> 
> Obviously if the list has only 20 elements, the core dump
> is actually a good thing since it will show you the error immediately.
> 
> Before returning, the "GetElement" API calls the error function
> and will return ONLY IF the error function returns.
> 
> I was relying in that as error handling, and just returning zero...
> 
> After some reflection I am convinced now that this would be a bad design
> decision.
> 
> What do you think?

I would go for a solution similar to what some (already) standard
functions do when they could return optional information. Have an
additional pointer argument to store that information. If that pointer
argument is 0, the user isn't interested.

(You could combine that with techniques that provide the feature of
optional arguments to C functions/macros in a way that most users
wouldn't actually have to know that this optional parameter exists.)

Jens

[toc] | [prev] | [next] | [standalone]


#22644

From"Joe." <antelope3@news.net>
Date2012-06-25 00:27 -0600
Message-ID<js901p$5d7$1@speranza.aioe.org>
In reply to#22497
"Design decisions"? As in, you can't design your way out of a paper bag but 
"the interrape" is a place to get what you want: something for nothing?

As is my nature, I should just ask questions:

What is "the interrape"?
Are other species of life <> than humans?

"jacob navia" <jacob@spamsink.net> wrote in message 
news:jrvvlb$8k1$1@speranza.aioe.org...
> In the new

As if the readers of this USENET discussion group actually gave a shit about 
your "old" "offering".

As it stands, jake the snake, no one needs to wait for you to grow up, 
because youth is growing up faster around you than you may realize. That 
said, I don't mean to push a weak person like you into the grave or to do 
something wrong. That said, this is not an offer for help. If you want to 
flame around C programming as some kind of "guru", ... can you do anything 
else? You really suck at software development, at the large... perhaps a 
role in a VERY structured environment where you can twiddle bits and be 
slapped on the knuckles at every juncture for your failure to grasp your 
"role" in that environment... I digress.

Politics have hurt not only you, but all people. You may find for yourself 
that you have no place to work, because ... why? I'm hardly one to avoid 
characterization (true/false/evil/whatever). Ha! I find myself in what I 
wrote "no place to work", that is, of course, the proverb of the falacy of 
"job" (not the saint, but rather the verbage of the politician's tongue, 
hopefully to soon be known as verbage of politician tongue).

So, what is "a job"? Why do politicians spew such verbage and not define it?

Oh, I have lots of questions. But of course my "job" requires compensation 
to keep up the good work. Else you can take this "job" and shove it.

*****

But I digress. (TBD).

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.c


csiph-web