bw*****@yahoo.com said:
In some APIs, we see char ** or void ** as a parameter. I never
distinguished between declaring a variable as char **x and passing x as
the parameter from declaring a variable char *x and passing &x. I also
consider the two the same.
Clearly, they aren't.
char *x;
char **y;
strtod(s, &x); /* &x is the address of an object of type char *. */
strtod(s, y); /* y is an indeterminate value */
And since I debug everything I write, I
also saw know difference while debugging.
You have now learned - I hope - that debugging is not sufficient. You have
to know what you're doing, too.
<snip>
What I would like to know is what is the proper way to handle APIs that
have functions with void ** parameters.
It depends on what those functions are trying to do. Knowing the prototype
for a function is insufficient. You have to understand the semantics of
that function, too.
In the case of strtod, what it is trying to tell you is the address of a
character - the first character it couldn't convert. If it were written
like this: char *strtod(char *s); that would be an easier way for it to
tell you that address, but then it wouldn't be able to return the double!
And it can't just be written like this: double strtod(char *s, char
*endptr); because if it were, it wouldn't matter how much strtod tried to
change the value of endptr - it would have no effect whatsoever on the char
* that you passed in! That's because C is a pass-by-value language, always.
And so strtod's designer(s) went for the next option, which is to take the
address of a char * object. Why? So that they can store into that char *
object the address of the first character they couldn't convert. Now, for
that to be a legitimate thing to do, that object must ***exist***! And
that's why it's insufficient to use char **endptr; What you /could/ do is
this:
char *endptr;
char **intermediatevalue = &endptr;
double d = strtod(s, intermediatevalue);
and endptr now points to the first unconverted character. That code would
have just the same validity, because now the value you are passing to
strtod really is the address of a valid object.
One interesting item brought up is that I might end up overwriting a
previously declared variable.
The C Standard does not place limits on the possible outcomes of undefined
behaviour.
--
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)