"Frederick Gotham" <fg*******@SPAM.comwrote in message
news:SD*******************@news.indigo.ie
John Carson:
>You can't "simply subtract pointers" and get a byte measure without a
cast (unless you have char* pointers to begin with),
Correct.
>so the advantage of
pointers is not obvious.
It's obvious to me... but then again I know what I'm doing.
>Using integers is more natural when you are
doing integer arithmetic (as opposed to pointer arithmetic) on
addresses.
What planet are you on? I hope you don't work professionally as a C++
programmer, do you?
Insults designed to cover up weakness in argument or to try to bully people
into sharing your personal preferences are out of place. You have made a
succession of false claims in previous posts and continue to make them in
this one. A better quality of argument would impress me. Insults don't. In
fact the combination of your rudeness and inaccuracy makes me reluctant to
converse with you.
The reference to "natural", by the way, does not imply that one approach is
correct and the other incorrect. Look up "natural" in a dictionary.
Here's some code that will work perfectly:
struct MyPOD {
int a;
char b;
void *c;
double d;
} obj;
ptrdiff_t distance_a_to_d = (char*)&obj.d - (char*)&obj.a;
It may work perfectly, but it has unspecified behaviour. By 5.2.10/7 of the
C++ Standard:
"A pointer to an object can be explicitly converted to a pointer to an
object of different type. Except that converting an rvalue of type "pointer
to T1" to the type "pointer to T2" (where T1 and T2 are object types and
where the alignment requirements of T2 are no stricter than those of T1) and
back to its original type yields the original pointer value, the result of
such a pointer conversion is unspecified."
Since your code does not convert back to the original type, the result is
unspecified.
I'll give you the benefit of the doubt and pretend that the address
of a byte can be accurately stored in an unsigned long. Even still,
the behaviour of the following is undefined:
ptrdiff_t distance_a_to_d =
(long unsigned)&obj.d - (long unsigned)&obj.a;
The right-hand side is not undefined, it is implementation-defined. I have
already given the passage from the Standard that says so. Assignment to the
left-hand side is then a matter of assigning one integral type to another,
which raises the standard issues associated with such assignments.
The C++ Standard gives no indication whatsoever as to how an address
should be represented numerically. By adding 1 to the integer form of
an address, you could be adding half a byte for all you know, or a
quarter of a byte, or an eighth of a byte.
True enough, but, as I have shown above, it likewise guarantees nothing
about what happens to address values when a pointer is cast to a new type
(except that casting it back unchanged gives the original value). Thus one
is forced to rely on details of the implementation when either approach is
used.
>>2: The C++ Standard doesn't necessitate the existance of an integer
type which can hold a byte address accurately.
It also doesn't guarantee that std::ptrdiff_t or any other type can
hold
(char const volatile*)pb - (char const volatile*)pa;
Of course it does. What do you think ptrdiff_t is for? Making
candy-floss?
No, it is for storing the result of pointer arithmetic. However, the
standard doesn't guarantee that it will be large enough to do so. By Section
5.7/6:
"When two pointers to elements of the same array object are subtracted, the
result is the difference of the subscripts of the two array elements. The
type of the result is an implementation-defined signed integral type; this
type shall be the same type that is defined as ptrdiff_t in the <cstddef>
header (18.1). As with any other arithmetic overflow, if the result does not
fit in the space provided, the behavior is undefined."
>On many platforms (Windows, in particular) there is a type that will
hold a byte address accurately. Indeed, Windows provides an integer
type called UINT_PTR which is specifically for this purpose.
Don't mention Windows to me. Microsoft and all of its programming
practises are utterly retarded.
I see we have left the realm of rational discussion and you are now treating
us to a display of your bile.
I take any need to mention Microsoft as an argument in my favour.
That explains a lot.
>>3: Even if such an integer type exists, the behaviour of performing
arithmetic upon the integer value and then casting back to a pointer
type is not defined by the C++ Standard.
Nor is it defined if you work with a char* pointer.
Of course it is.
It isn't. See above. The result is only defined if you cast back to the
original pointer type without changing the value of the char* pointer. If
you change the value of the char* pointer before casting back, you are in
the realm of undefined behaviour.
The address of any byte in memory (whether it be
part of a POD, intrinsic type, union, class object, whatever) can be
accurately stored in either of:
void*
char*
char signed*
char unsigned*
"Accurately stored" is rather ambiguous. What is not defined is the end
result of the following three operations performed in succession:
1. Casting to any of the pointers you list.
2. Modifying the pointer value.
3. Casting back to the original pointer type.
--
John Carson