so how do I do it? (was Re: call to revolt)
John F. Woods
jfw at ksr.com
Sat Jun 29 01:23:31 AEST 1991
minar at reed.edu writes:
>If
>void * p;
>(int *)p++;
>is illegal, how do I do what I mean?
Since it is illegal, you'll have to explain what you WANT it to main.
>I'm writing some code right now that needs to extract information from a
>buffer that contains various types in it. Lets say that there's a chunk of
>memory that I *know* first contains a char, then an unsigned. I want to get
>these values.
Ah.
>The obvious way to do it is
>struct foo {
> char c;
> unsigned u;
>};
>and then (struct foo *)p->c or (struct foo *)p->u
>this is nonportable, as to my understanding, as struct arrangements are not
>guaranteed.
They are guaranteed. The address of p->c is guaranteed to be less than the
address of p->u. Of course, the PADDING is implementation defined.
>The next best thing is:
>*(char *)p
>to get the char.
Yes.
>Then, I want to get to the unsigned that's next, so the obvious next step is
>(char *)p++
Not it you plan to program in C.
p = (char *)p + sizeof(char);
will increment p by the size of a char. NOTE: I assume you think you can then
type
*(unsigned *)p
to get the value of the unsigned int which follows, and this is WRONG. A wide
variety of interesting (i.e. neither VAX nor washing-machine-controller)
machines will take addressing exceptions if you access objects on random
alignments. To access that unsigned int will require something like
unsigned int victim;
bcopy(p, &victim, sizeof(unsigned int)); /* or your favorite memory
* mover or even a carefully
* chosen macro
*/
p = (char *)p + sizeof(unsigned int);
But this, of course, assumes that the byte-order in that packed "structure"
is the same as the machine's natural byte-order; if you're exchanging these
"structures" with another machine (via disk file or network) that may not
be the case, in which case "accessor macros" are an excellent idea here (i.e.
the putlong()/getlong() macros found in the BSD named resolver routines).
This kind of problem has been solved correctly and well in C over and over
again.
>I don't have to write this code portably, but I'd like to write it correctly
>according to ANSI anyway.
Note that unportable code is not only a problem when you finally upgrade from
your 8080 system to a Laptop Cray; it can cause you grief the next time you
get a compiler upgrade (hahahahahahahahahahahaha) or even using the same
compiler, if it is an aggresive optimizer which prizes speed of code over
consistency in undefined cases.
>while I'm at it, how do you get the offset of an element of a structure
>the ANSI way?
Using the offsetof() macro. Please go buy and read an ANSI C manual.
"I'm having troubles with an Ada program; I don't actually have an Ada manual,
nor have I ever seen one, so I just typed in the following BASIC program, and
I don't understand why it doesn't work:"
More information about the Comp.std.c
mailing list