By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,373 Members | 1,792 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,373 IT Pros & Developers. It's quick & easy.

Casting void * to void ** ?

P: n/a
Hi All,

I have a question which might sound very basic.

I have a simple structure:

struct simple{
void *buffer;
};
typedef struct simple Simple;

In my function I do this:

void do_Something(){

Simple *simp_struct;
simp_struct->buffer = malloc(10 * sizeof(int *));

call_func((void **)((int **)(simp_struct->buffer)));
....
}

The function call_func has this prototype:
call_func(void **buf);

I am confused with this piece of code:
call_func((void **)((int **)(simp_struct->buffer)));

What does this construct mean? How is that simp_struct->buffer
(which is a void *) is being cast to a int** followed by a
cast to void ** and passed to call_func ?

Rgds.
Mirage
Apr 21 '06 #1
Share this Question
Share on Google+
31 Replies


P: n/a
Twister wrote:
Hi All,

I have a question which might sound very basic.

I have a simple structure:

struct simple{
void *buffer;
};
typedef struct simple Simple;

In my function I do this:

void do_Something(){

Simple *simp_struct;
simp_struct->buffer = malloc(10 * sizeof(int *));

call_func((void **)((int **)(simp_struct->buffer)));
....
}

The function call_func has this prototype:
call_func(void **buf);

I am confused with this piece of code:
call_func((void **)((int **)(simp_struct->buffer)));

What does this construct mean? How is that simp_struct->buffer
(which is a void *) is being cast to a int** followed by a
cast to void ** and passed to call_func ?

Rgds.
Mirage
I mistyped part of my previous mail:

This piece of code: I am confused with this piece of code:
call_func((void **)((int **)(simp_struct->buffer)));


should be this:

for(i=0; i<10 ;i++)
call_func((void **)((int **)simp_struct->buffer + i));

My question remains the same. What does the above
construct mean?

Rgds.
Mirage
Apr 21 '06 #2

P: n/a
Twister said:

<snip>
simp_struct->buffer = malloc(10 * sizeof(int *));

call_func((void **)((int **)(simp_struct->buffer)));
Why not just do this:

call_func(&simp_struct->buffer);

Casts are almost always wrong.

The function call_func has this prototype:
call_func(void **buf);

I am confused with this piece of code:
call_func((void **)((int **)(simp_struct->buffer)));

What does this construct mean?


It means you don't (or whoever wrote it doesn't) understand what casting is
for.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 21 '06 #3

P: n/a
In article <k8*************@news.oracle.com>,
Twister <tw*****@nospam.com> wrote:
struct simple{
void *buffer;
};
typedef struct simple Simple; void do_Something(){

Simple *simp_struct;
simp_struct is an uninitialized pointer after that statement.
simp_struct->buffer = malloc(10 * sizeof(int *));
But there you are using it as if it was initialized.
simp_struct->buffer involves dereferencing simp_struct first and
then accessing the structure component named buffer there, so
simp_struct needs to be given a value first.
call_func((void **)((int **)(simp_struct->buffer)));
....
}

--
Prototypes are supertypes of their clones. -- maplesoft
Apr 21 '06 #4

P: n/a
Walter Roberson said:
In article <k8*************@news.oracle.com>,
Twister <tw*****@nospam.com> wrote:
struct simple{
void *buffer;
};
typedef struct simple Simple;

void do_Something(){

Simple *simp_struct;


simp_struct is an uninitialized pointer after that statement.


Good spot. I didn't see that. Silly me.

Everything I said still applies, but that applies too!

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 21 '06 #5

P: n/a
Twister said:
for(i=0; i<10 ;i++)
call_func((void **)((int **)simp_struct->buffer + i));

My question remains the same. What does the above
construct mean?


That's a major difference.

What you have now is a bug.

simp_struct->buffer has type void *, so you can't do pointer arithmetic on
it. So the cast to int ** gives you a value (of type int **) with which you
/can/ do pointer arithmetic. That is, (int **)simp_struct->buffer + i gives
you the address of the i'th int **, starting at simp_struct->buffer. The
expression has type int **. The cast to void ** is an error because there
is no guarantee that an int ** can be copied to a void ** without loss of
information.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 21 '06 #6

P: n/a
Richard Heathfield wrote:
Twister said:

for(i=0; i<10 ;i++)
call_func((void **)((int **)simp_struct->buffer + i));

My question remains the same. What does the above
construct mean?

That's a major difference.

What you have now is a bug.

simp_struct->buffer has type void *, so you can't do pointer arithmetic on
it. So the cast to int ** gives you a value (of type int **) with which you
/can/ do pointer arithmetic. That is, (int **)simp_struct->buffer + i gives
you the address of the i'th int **, starting at simp_struct->buffer. The
expression has type int **. The cast to void ** is an error because there
is no guarantee that an int ** can be copied to a void ** without loss of
information.


simp_struct->buffer was earlier initialized to point to memory
of 10 (int *)'s. So isn't just saying, (int *)simp_struct->buffer + i
correct? Why cast it to an (int **), unless i'm not passing it
to a function which expects a int ** or a void ** ? Please correct
me if i'm wrong here.

Rgds.
Mirage
Apr 21 '06 #7

P: n/a
Twister said:
Richard Heathfield wrote:
Twister said:

for(i=0; i<10 ;i++)
call_func((void **)((int **)simp_struct->buffer + i));

My question remains the same. What does the above
construct mean?

That's a major difference.

What you have now is a bug.

simp_struct->buffer has type void *, so you can't do pointer arithmetic
on it. So the cast to int ** gives you a value (of type int **) with
which you /can/ do pointer arithmetic. That is, (int
**)simp_struct->buffer + i gives you the address of the i'th int **,
starting at simp_struct->buffer. The expression has type int **. The cast
to void ** is an error because there is no guarantee that an int ** can
be copied to a void ** without loss of information.


simp_struct->buffer was earlier initialized to point to memory
of 10 (int *)'s. So isn't just saying, (int *)simp_struct->buffer + i
correct?


No, that would point to the i'th int, not the i'th int *.
Why cast it to an (int **),
To get a pointer to the i'th int *.
Please correct me if i'm wrong here.


The cast to int ** is correct, but doesn't help you solve your void **
problem.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 21 '06 #8

P: n/a
Richard Heathfield wrote:
Twister said:

Richard Heathfield wrote:
Twister said:

for(i=0; i<10 ;i++)
call_func((void **)((int **)simp_struct->buffer + i));

My question remains the same. What does the above
construct mean?
That's a major difference.

What you have now is a bug.

simp_struct->buffer has type void *, so you can't do pointer arithmetic
on it. So the cast to int ** gives you a value (of type int **) with
which you /can/ do pointer arithmetic. That is, (int
**)simp_struct->buffer + i gives you the address of the i'th int **,
starting at simp_struct->buffer. The expression has type int **. The cast
to void ** is an error because there is no guarantee that an int ** can
be copied to a void ** without loss of information.

simp_struct->buffer was earlier initialized to point to memory
of 10 (int *)'s. So isn't just saying, (int *)simp_struct->buffer + i
correct?

No, that would point to the i'th int, not the i'th int *.

Why cast it to an (int **),

To get a pointer to the i'th int *.

Please correct me if i'm wrong here.

The cast to int ** is correct, but doesn't help you solve your void **
problem.


Thanks. That clarified part of my question.
The cast to void ** is an error because there is no guarantee that an
int ** can be copied to a void ** without loss of information.


The malloc just allocated enough space for 10 (int *) pointers.
The pointers themselves are not pointing to valid memory. So If I cast
simp_struct->buffer finally to a void **(after the cast to an int **)
and pass it to a function which allocates some momory and points these
int *'s to valid memory, am I not doing the right thing ? Where is the
loss of information happening ?

Rgds.
Mirage
Apr 21 '06 #9

P: n/a
Twister said:
Richard Heathfield wrote:
>The cast to void ** is an error because there is no guarantee that an
>int ** can be copied to a void ** without loss of information.
The malloc just allocated enough space for 10 (int *) pointers.


Yes.
The pointers themselves are not pointing to valid memory.
Right.
So If I cast
simp_struct->buffer finally to a void **(after the cast to an int **)
and pass it to a function which allocates some momory and points these
int *'s to valid memory, am I not doing the right thing ?
No, I'm afraid not.
Where is the loss of information happening ?


There's no guarantee that information is lost. There's just no guarantee
that it's not lost! Either could happen. In other words, it might "work"
just fine on your development machine - and then break on some other box.

The problem is that, whilst the Standard guarantees that you can use void *
to store any object pointer (without loss of information), it doesn't offer
the same guarantee for void **.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 21 '06 #10

P: n/a

"Richard Heathfield" <in*****@invalid.invalid> wrote in message
news:Ls********************@bt.com...
Walter Roberson said:
In article <k8*************@news.oracle.com>,
Twister <tw*****@nospam.com> wrote:
struct simple{
void *buffer;
};
typedef struct simple Simple;

void do_Something(){

Simple *simp_struct;


simp_struct is an uninitialized pointer after that statement.


Good spot. I didn't see that. Silly me.

Everything I said still applies, but that applies too!


I've been looking for some common notions that I thought I had read in your
book. I was hoping you might help me find them. Joe
----------
C drifts
and seems

But now,
I'm piffed
and meeved

and in a bad mood
Apr 30 '06 #11

P: n/a
Joe Smith said:
I've been looking for some common notions that I thought I had read in
your
book. I was hoping you might help me find them. Joe


I've been in RL for a few days, and I seem to have lost the plot here. If
you could make it clearer what you're after, I'll be happy to do what I can
to help you in your search.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 30 '06 #12

P: n/a
Richard Heathfield wrote:
Joe Smith said:
I've been looking for some common notions that I thought I had
read in your book. I was hoping you might help me find them.


I've been in RL for a few days, and I seem to have lost the plot
here. If you could make it clearer what you're after, I'll be
happy to do what I can to help you in your search.


OT - what is an RL?

--
"Churchill and Bush can both be considered wartime leaders, just
as Secretariat and Mr Ed were both horses." - James Rhodes.
"We have always known that heedless self-interest was bad
morals. We now know that it is bad economics" - FDR
Apr 30 '06 #13

P: n/a
ed
On Sun, 30 Apr 2006 08:16:56 -0400
CBFalconer <cb********@yahoo.com> wrote:
OT - what is an RL?


Real Life I think, the AP was talking about spending time away from the
computer I believe.

--
Regards, Ed :: http://www.s5h.net
:%s/Open Source/Free Software/g :: Free DNS available

Apr 30 '06 #14

P: n/a
CBFalconer said:
Richard Heathfield wrote:
Joe Smith said:
I've been looking for some common notions that I thought I had
read in your book. I was hoping you might help me find them.


I've been in RL for a few days, and I seem to have lost the plot
here. If you could make it clearer what you're after, I'll be
happy to do what I can to help you in your search.


OT - what is an RL?


It's what happens to you when you pop into the Big Room for a while (the one
with the really high grey-blue ceiling and imitation artificial light).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 30 '06 #15

P: n/a
Richard Heathfield schrieb:
CBFalconer said:
Richard Heathfield wrote:
Joe Smith said:
I've been looking for some common notions that I thought I had
read in your book. I was hoping you might help me find them.

I've been in RL for a few days, and I seem to have lost the plot
here. If you could make it clearer what you're after, I'll be
happy to do what I can to help you in your search.


OT - what is an RL?


It's what happens to you when you pop into the Big Room for a while (the one
with the really high grey-blue ceiling and imitation artificial light).


Oh, the one with the incredibly high resolution and artifact-free
animation? I don't know, about half the time the sprinkler system or
the air conditioning is defect. The worst thing, though, is that you
cannot change the options.

-Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Apr 30 '06 #16

P: n/a
Michael Mair said:
Richard Heathfield schrieb:
CBFalconer said:
Richard Heathfield wrote:
Joe Smith said:
>I've been looking for some common notions that I thought I had
>read in your book. I was hoping you might help me find them.

I've been in RL for a few days, and I seem to have lost the plot
here. If you could make it clearer what you're after, I'll be
happy to do what I can to help you in your search.

OT - what is an RL?


It's what happens to you when you pop into the Big Room for a while (the
one with the really high grey-blue ceiling and imitation artificial
light).


Oh, the one with the incredibly high resolution and artifact-free
animation? I don't know, about half the time the sprinkler system or
the air conditioning is defect. The worst thing, though, is that you
cannot change the options.


A source (who wishes to remain anonymous!) has asked me, on the off-chance
that the maintenance team read clc, to add that the thermostat is broken.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 30 '06 #17

P: n/a
[funny stuff snipped]

I've been writing elementary programs to knock some of the rust off my game
here. Both Professors Knuth and Gallian start with Euclid's algortihm. I
would like to implement it with the memory techniques at the beginning of
_Unleashed_ Should I start clean with a new thread? I must say, while I
didn't catch why a person would want cast a void * to void**, it doesn't
sound like a very good idea. Joe
Apr 30 '06 #18

P: n/a
Joe Smith said:
[funny stuff snipped]

I've been writing elementary programs to knock some of the rust off my
game
here. Both Professors Knuth and Gallian start with Euclid's algortihm. I
would like to implement it with the memory techniques at the beginning of
_Unleashed_
I'm not sure why you'd need memory techniques for Euclid's Algorithm.

You can find an implementation on p326 of CU. Alternatively, here's my own,
relatively straightforward, implementation of Knuth's description of
Euclid's Algorithm in TAOCP:

unsigned long gcd(unsigned long m, unsigned long n)
{
if(n == 0)
{
/* Caller doesn't know what he's doing. It's not
* our job to bomb out, so we'll simply return an
* impossible result - 0 - to match our impossible
* input.
*/
}
else if(m < n)
{
n = gcd(n, m);
}
else
{
unsigned long r = m % n;
if(r > 0)
{
n = gcd(n, r);
}
}
return n;
}

Should I start clean with a new thread? I must say, while I
didn't catch why a person would want cast a void * to void**, it doesn't
sound like a very good idea.


I see no need for it, and you're right - it sounds like a bad idea. Not bad
in itself, exactly, but it's a hint that someone, somewhere, is either
assuming or just hoping(!) that void ** carries with it the same guarantees
that void * does - but, alas, this is not the case.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 1 '06 #19

P: n/a

"Richard Heathfield" opined:
Joe Smith said:
I've been writing elementary programs to knock some of the rust off my
game
here. Both Professors Knuth and Gallian start with Euclid's algortihm.
I
would like to implement it with the memory techniques at the beginning of
_Unleashed_


I'm not sure why you'd need memory techniques for Euclid's Algorithm.

You can find an implementation on p326 of CU. Alternatively, here's my
own,
relatively straightforward, implementation of Knuth's description of
Euclid's Algorithm in TAOCP:

unsigned long gcd(unsigned long m, unsigned long n)
{
if(n == 0)
{
/* Caller doesn't know what he's doing. It's not
* our job to bomb out, so we'll simply return an
* impossible result - 0 - to match our impossible
* input.
*/
}
else if(m < n)
{
n = gcd(n, m);
}
else
{
unsigned long r = m % n;
if(r > 0)
{
n = gcd(n, r);
}
}
return n;
}

Should I start clean with a new thread? I must say, while I
didn't catch why a person would want cast a void * to void**, it doesn't
sound like a very good idea.


I see no need for it, and you're right - it sounds like a bad idea. Not
bad
in itself, exactly, but it's a hint that someone, somewhere, is either
assuming or just hoping(!) that void ** carries with it the same
guarantees
that void * does - but, alas, this is not the case.


'void**' reminds me of the Escher drawing of the hand drawing the hand and
the peculiar way Goedel regarded his. I'll fire up that source you posted
when I begin my campaign tomorrow to Take Over the Week. My methods for
handling memory are childish. I think what I'll try to do is take the
eratosthenos algorithm down yonder and have the user tell the prog how large
an N we have. Joe
---------
My hat usually has 3 corners but tonight has none.
May 1 '06 #20

P: n/a

Richard Heathfield wrote, in reference to casting void * to void **:
I see no need for it, and you're right - it sounds like a bad idea. Not bad
in itself, exactly, but it's a hint that someone, somewhere, is either
assuming or just hoping(!) that void ** carries with it the same guarantees
that void * does - but, alas, this is not the case.


There's a perfectly valid reason for it: here's a function that takes
a pointer to a multidimensional array of unknown size, and dereferences
a value. (or, rather, returns a void pointer to the requested value,
which the caller can then dereference, since the caller knows the
type.)

void *dereference_array(void *A, int dim, unsigned int *coord)
{
if (dim ==1)
return (void **)A + coord[0];
else
return dereference_array(*((void **)(A)+coord[0]), dim-1,
coord+1);
}

May 1 '06 #21

P: n/a
Joe Smith said:
'void**' reminds me of the Escher drawing of the hand drawing the hand and
the peculiar way Goedel regarded his.
Escher is more like this: void *e = &e; /* self-reference */

Goedel: volatile int *g = (int *)&PROBLEM; assert(g == g); /* might fire */

I'll fire up that source you posted
when I begin my campaign tomorrow to Take Over the Week. My methods for
handling memory are childish. I think what I'll try to do is take the
eratosthenos algorithm down yonder and have the user tell the prog how
large
an N we have.


Eratosthenes' Sieve is a completely different kettle of fish to Euclid's
Algorithm, and is perhaps a much better example of where you might need to
manage memory in some significant way. You can cut down on the amount of
RAM you need for the Sieve by using bits as flags, and by not bothering
with, say, even numbers, but if you want to build a seriously big Sieve,
you're going to need some serious RAM. For example, even if you restrict
yourself to, say, 32-bit unsigned integers, and don't bother to represent
even numbers (even though ignoring them makes your loop a bit more fiddly),
and use 1 bit per number, you still need 2^31 bits, or 2^27 bytes. This is
about 128 MB!

There are, incidentally, faster and less memory-intensive ways to determine
primality.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 1 '06 #22

P: n/a
In article <-Y******************************@bt.com>,
Richard Heathfield <in*****@invalid.invalid> wrote:
Joe Smith said:
'void**' reminds me of the Escher drawing of the hand drawing the hand and
the peculiar way Goedel regarded his.

Escher is more like this: void *e = &e; /* self-reference */


The scope of the variable e does not begin until after the end of
its declarator, so the second appearance of e in that expression
is not a reference to the first. Also, &e would be of type void **
which brings us back to the discussion about whether void ** will
be converted to void * by an assignment...
--
Prototypes are supertypes of their clones. -- maplesoft
May 1 '06 #23

P: n/a

"Richard Heathfield"
Joe Smith said:
'void**' reminds me of the Escher drawing of the hand drawing the hand
and
the peculiar way Goedel regarded his.
Escher is more like this: void *e = &e; /* self-reference

But there's two hands:
while (condition)
{
*g = &f;
*f = &g;
}

Goedel: volatile int *g = (int *)&PROBLEM; assert(g == g); /* might fire
*/

Actually, I was talking about how the cat walked around looking like
Nosferatu with long, black gloves. You gotta wonder about how his neural
pathways looked on the instruments capable of doing f, f**-1 .
I'll fire up that source you posted

presently. Joe
May 1 '06 #24

P: n/a
On 2006-05-01, Walter Roberson <ro******@ibd.nrc-cnrc.gc.ca> wrote:
In article <-Y******************************@bt.com>,
Richard Heathfield <in*****@invalid.invalid> wrote:
Joe Smith said:

'void**' reminds me of the Escher drawing of the hand drawing the hand and
the peculiar way Goedel regarded his.

Escher is more like this: void *e = &e; /* self-reference */


The scope of the variable e does not begin until after the end of
its declarator, so the second appearance of e in that expression
is not a reference to the first. Also, &e would be of type void **
which brings us back to the discussion about whether void ** will
be converted to void * by an assignment...


Are you sure? It Seems To Work (tm) on GCC, and for it to work would be
a violation of the standard if it says what you think it says.

(and, yes, void ** will be converted to void * by assignment. why
wouldn't it be?)
May 1 '06 #25

P: n/a

"Richard Heathfield"
Joe Smith said:
[funny stuff snipped]

I've been writing elementary programs to knock some of the rust off my
game
here. Both Professors Knuth and Gallian start with Euclid's algortihm.
I
would like to implement it with the memory techniques at the beginning of
_Unleashed_
I'm not sure why you'd need memory techniques for Euclid's Algorithm.

You can find an implementation on p326 of CU. Alternatively, here's my
own,
relatively straightforward, implementation of Knuth's description of
Euclid's Algorithm in TAOCP:


You and Knuth solved this using recursion, where the computer worries about
providing for its own memory.
unsigned long gcd(unsigned long m, unsigned long n)
{
if(n == 0)
{
/* Caller doesn't know what he's doing. It's not
* our job to bomb out, so we'll simply return an
* impossible result - 0 - to match our impossible
* input.
Interesting way to say it.
*/
}
else if(m < n)
{
n = gcd(n, m);
}
else
{
unsigned long r = m % n;
if(r > 0)
{
n = gcd(n, r);
}
}
return n;
}

[snip]
For better or worse, I'm going to attempt sieve4.c in which
p = malloc(n + 1);
appears. It would seem to me to be a necessary skill. Joe
May 1 '06 #26

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <-Y******************************@bt.com>,
Richard Heathfield <in*****@invalid.invalid> wrote:
Escher is more like this: void *e = &e; /* self-reference */
The scope of the variable e does not begin until after the end of
its declarator,


This is correct.
so the second appearance of e in that expression is not a
reference to the first.


This is wrong. Declarations and declarators are distinct
concepts. The declarator is *e. The initializer follows the
declarator.
--
"IMO, Perl is an excellent language to break your teeth on"
--Micah Cowan
May 1 '06 #27

P: n/a
On 2006-05-01, Joe Smith <gr**********@netzero.net> wrote:

"Richard Heathfield"
Joe Smith said:
[funny stuff snipped]

I've been writing elementary programs to knock some of the rust off
my game here. Both Professors Knuth and Gallian start with Euclid's
algortihm. I would like to implement it with the memory techniques
at the beginning of _Unleashed_


I'm not sure why you'd need memory techniques for Euclid's Algorithm.

You can find an implementation on p326 of CU. Alternatively, here's
my own, relatively straightforward, implementation of Knuth's
description of Euclid's Algorithm in TAOCP:


You and Knuth solved this using recursion, where the computer worries about
providing for its own memory.


This can be done iteratively. Mechanical iterative conversion below,
probably should be rewritten to use a real loop.
unsigned long gcd(unsigned long m, unsigned long n)
{ + top: if(n == 0)
{
/* Caller doesn't know what he's doing. It's not
* our job to bomb out, so we'll simply return an
* impossible result - 0 - to match our impossible
* input.


Interesting way to say it.
*/
}
else if(m < n)
{ ->> n = gcd(n, m);
+ int tmp = n;
+ n = m;
+ m = tmp;
+ goto top; }
else
{
unsigned long r = m % n;
if(r > 0)
{ + m = n; n = r;
+ goto top;
->> n = gcd(n, r); }
}
return n;
}

[snip]
For better or worse, I'm going to attempt sieve4.c in which
p = malloc(n + 1);
appears. It would seem to me to be a necessary skill. Joe

May 1 '06 #28

P: n/a
Walter Roberson said:
In article <-Y******************************@bt.com>,
Richard Heathfield <in*****@invalid.invalid> wrote:
Joe Smith said:
'void**' reminds me of the Escher drawing of the hand drawing the hand
and the peculiar way Goedel regarded his.

Escher is more like this: void *e = &e; /* self-reference
*/


The scope of the variable e does not begin until after the end of
its declarator,


Right.
so the second appearance of e in that expression
is not a reference to the first.
Wrong. But you can have a consolation prize - it was something similar that
prompted Dan Pop to say "the expression isn't unclear *at all*, and only an
expert could possibly have any doubts about it".
Also, &e would be of type void **
Right. So?
which brings us back to the discussion about whether void ** will
be converted to void * by an assignment...


It will. An automatic conversion is supplied in the special case of void *
(in either direction), as I'm sure you knew already but had temporarily
forgotten.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 1 '06 #29

P: n/a
Joe Smith said:

"Richard Heathfield"

I'm not sure why you'd need memory techniques for Euclid's Algorithm.

You can find an implementation on p326 of CU. Alternatively, here's my
own,
relatively straightforward, implementation of Knuth's description of
Euclid's Algorithm in TAOCP:


You and Knuth solved this using recursion, where the computer worries
about providing for its own memory.


Actually, I did but Knuth didn't. Here is an even more straightforward
implementation of Knuth's description of Euclid's Algorithm in TAOCP,
without using recursion:

unsigned long gcd(unsigned long m, unsigned long n)
{
if(m < n)
{
unsigned long temp = m;
m = n;
n = temp;
}
if(n > 0)
{
unsigned long r;
do
{
r = m % n;
m = n;
n = r ? r : n;
} while(r > 0);
}

return n;
}

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 2 '06 #30

P: n/a

"Richard Heathfield"
Joe Smith said:
"Richard Heathfield"

I'm not sure why you'd need memory techniques for Euclid's Algorithm.
The reason, for better or worse, that I think I need a memory technique
might have to do with the development as given by Gallian. We had the
division algorithm that would be guaranteed to terminate in a finite number
of steps, and then we had to rewrite all the equations and substitute, so as
to write a given N as a linear combo. I'm failing to see how this stack of
numbers behaves in your treatment. With a debugger that is only telling me
'no matching symbolic information found', I am unable to step through.
You can find an implementation on p326 of CU. Alternatively, here's my
own,
relatively straightforward, implementation of Knuth's description of
Euclid's Algorithm in TAOCP:


You and Knuth solved this using recursion, where the computer worries
about providing for its own memory.


Actually, I did but Knuth didn't. Here is an even more straightforward
implementation of Knuth's description of Euclid's Algorithm in TAOCP,
without using recursion:

unsigned long gcd(unsigned long m, unsigned long n)
{
if(m < n)
{
unsigned long temp = m;
m = n;
n = temp;
}
if(n > 0)
{
unsigned long r;
do
{
r = m % n;
m = n;
n = r ? r : n;
} while(r > 0);
}

return n;
}

I guess what I'll do is add some printf's and breaks and do some figgerin.
Joe
May 2 '06 #31

P: n/a

"Richard Heathfield" <in*****@invalid.invalid> wrote in message
news:ie********************@bt.com...
Joe Smith said:

"Richard Heathfield"

I'm not sure why you'd need memory techniques for Euclid's Algorithm.

You can find an implementation on p326 of CU. Alternatively, here's my
own,
relatively straightforward, implementation of Knuth's description of
Euclid's Algorithm in TAOCP:


You and Knuth solved this using recursion, where the computer worries
about providing for its own memory.


Actually, I did but Knuth didn't. Here is an even more straightforward
implementation of Knuth's description of Euclid's Algorithm in TAOCP,
without using recursion:

unsigned long gcd(unsigned long m, unsigned long n)
{
if(m < n)
{
unsigned long temp = m;
m = n;
n = temp;
}
if(n > 0)
{
unsigned long r;
do
{
r = m % n;
m = n;
n = r ? r : n;
} while(r > 0);
}

return n;
}


Bear with me, please. Elsethread:
news:44**********************@news.usenetmonster.c om...
I've elaborated on this theme and seek comment. I have a debugger now, so
my programming IQ just got a bump. Joe
May 4 '06 #32

This discussion thread is closed

Replies have been disabled for this discussion.