🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.c.moderated
2 messages
2 total messages Started by Chris Torek Mon, 08 Apr 1996 16:20
Re: (double **) void **
#2552
Author: Chris Torek
Date: Mon, 08 Apr 1996 16:20
66 lines
3185 bytes
(I started this out as mail but decided to send it to the newsgroup
as well.)

In article <4k60po$aic@solutions.solon.com> thomas@eel.rdc.toshiba.co.jp
writes:
>The function is listed below, and I'd like to know if it is legal.

`Legal' is not a well-defined term.  The code is not strictly
conformant (depends on both implementation-defined and undefined
behaviour).  It will probably *work* on most systems.

>  m = (void **) calloc(len_d1, sizeof(void *));       /* Is (void **) a   */
>  if(!m) nrerror("allocation failure 1 in matrix()"); /*  valid data type?*/

Yes, `void **' is a valid data type.  Here calloc() allocates len_d1
objects of type `void *' (or returns NULL).

The cast is redundant, since `calloc' is declared in <stdlib.h> and
has type `void *'.

Using calloc() instead of malloc() offers no real advantage (although
some people argue that you might be able to allocate more memory
via calloc() than via malloc(), since malloc requires that you
multiply your two size_t's yourself, which might overflow).  The
calloc() function sets the newly-allocated memory to all-bits-zero,
which is not a useful pointer value.

>    for(len_d1--; 0 <= len_d1; len_d1--) {
>	m[len_d1] = (void *) calloc(len_d2, tsize); ...

This cast is similarly redundant.  Again, calloc() buys little in
this particular case, since all-bits-zero is not a useful `double'
value; of course, matrix() does not really know that the memory
will be used to hold doubles.

>   double **m;
>   m = (double **) matrix(10, 10, sizeof(double)); 

The effect of this conversion is undefined.  The matrix() function
has returned a pointer of type `void **', pointing to the first of
10 `void *'s.  You can use these `void *'s via, e.g.,

	void **m;
	double *p;

	m = matrix(10, 10, sizeof(double));
	p = m[i];	/* 0 <= i < 10; causes a conversion */
	... now can use p[j], where 0 <= j < 10 ...

Note that the conversion from `void *' to `double *' is well-defined,
since each of the `void *'s in m[i] came from a successful calloc();
p[j] is likewise well-defined, because it has been converted properly.

If you simply convert the `void **' to a `double **', the effect
is implementation-defined.  The resulting `double **' value, whatever
it is, does not really point to `double *'s, and the effect of
accessing any of them is undefined.

The key to understanding this is that the cast performs a conversion,
and the conversion must be done from `void *' to whatever-the-correct-
type-is.  It can be deferred (as with the `p = m[i]' line), but it
must eventually be done, and it must be done on the `void *' that
calloc() (or malloc()) returned.
-- 
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA	Domain:	torek@bsdi.com	+1 510 234 3167
Re: (double **) void **
#2558
Author: Chris Torek
Date: Tue, 09 Apr 1996 03:46
18 lines
1137 bytes
I hate to have to follow up to my own article, but...

In article <4kbebt$eiv@solutions.solon.com> I wrote:
>>   double **m = (double **) [expression of type `void **']

>The effect of this conversion is undefined. ... the effect
>is implementation-defined.

Clearly the effect cannot be both undefined and implementation-
defined!

I think (from 3.3.4) that `undefined' is correct here (since there
is no known relationship between the alignment constraints for
`void **' and `double **').  In any case, however, portable code
must not depend on the result.
-- 
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA	Domain:	torek@bsdi.com	+1 510 234 3167
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads