Re: is this code valid?
On Jun 4, 5:43 pm, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.com> wrote:
> James Kanze wrote:
> > On Jun 4, 1:36 am, "jason.cipri...@gmail.com"
> > <jason.cipri...@gmail.com> wrote:
> > > You can pass any data pointer, it's all the same.
> > That is simply false. Technically, you can only pass a void*; I
> > don't see anything in ISO/IEC 9899 which would even allow void
> > const*. In practice, unless the implementation explicitly
> > verifies, you'll also be able to pass char* and char const*,
> > since they are required to have the same size and representation
> > as a void*. Anything else is undefined behavior, and ...
> I did not know that. Is that to say that these two statements
> are not the same:
> int i;
> int *k = &i;
> void *a = *(void **)&k; // <--- this
> void *b = (void *)k; // <--- and this
Certainly not. The first is undefined behavior, and will result
in a more or less random value for a on some processors.
> Or does that only mean that fprintf with %p is undefined
> unless you explicitly cast pointer parameters to (void *)
> first?
Correct.
> I could've sworn that somewhere in C++ it said that the
> representation for data pointers was always the same -- do you
> know where the relevant part of the standard is (looking in
> C++03, I couldn't find anything relevant).
I'm not sure I understand. You want me to point out in the
standard where the guarantee isn't given. The real question is
the reverse: what makes you think that an int* has the same size
and layout as a void*.
The fact that the standard feels it necessary to offer some
limited guarantees should be a strong indication, however (from
§3.9.2, paragraphs 3 and 4, from the 1998 version, since that
and the current draft are all I have on line here):
[...] The value representation of pointer types is
implementation-defined. Pointers to cv-qualified and
cv-unqualified version of layout-compatible types shall have
the same value representation and alignment requirements.
Objects of cv-qualified or cv-unqualified type void*
(pointer to void) can be used to point to objects of unknown
type. A void* shall be able to hold any object pointer. A
cv-qualified or cv-unqualified void* shall have the same
representation and alignment requiremns as a cv-qualified or
cv-unqualified char*.
In other words: const and non-const pointers to the same type
(or a layout compatible type) must have the same representation,
and void* and char* must have the same representation. In
addition, the way incomplete types can be used more or less
forces an implementation to use the same representation for all
pointers to class types. (The only thing the representation
could depend on is the spelling of the class name, which is, of
course, ridiculous.)
You might also look at the guarantees concerning casts---it's
quite clear that casting a void* to int* and back is not
guaranteed to result in the original pointer. That's there for
a reason.
> > ...I've worked on machines where it would cause random junk
> > to be output ...
> Just out of curiosity, what machines cause things like
> printf("%p", (int *)&something); to print random junk?
Word addressed machines. The machine in question had
sizeof(int*) == 2, but sizeof(char*) == 4; the basic hardware
pointer (16 bits) addressed words, and not bytes, and you needed
additional bits (an additional word) to access individual bytes.
Not so many years ago, this was the most frequent arrangment.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|