Date: Mon, 18 May 2015 12:55:26 -0700
I posted this to std-discussion, but I figured I might get more response
from the undefined-behavior list instead.
The C++ Standard permits you to use offsetof() on standard-layout classes,
but does it permit using that offset in pointer arithmetic with object
pointers that have been reinterpret_cast to [unsigned] char *?
The section on pointer arithmetic is predicated on "if the pointer object
points to an element of an array object" (§5.7/4), with undefined behavior
otherwise. It has a footnote stating that, "an object that is not an array
is considered to belong to a single-element array for this purpose". But
if you reinterpret_cast a pointer to a single object into a char pointer,
that's not a pointer to an array object.
Does this mean that doing pointer arithmetic on a reinterpret_cast char
pointer of a single object in order to reach other members is undefined
behavior even for standard-layout types? It seems to me that this was not
the intention of the Standard. Getting around this would require using
memcpy into a char array, only ever using the offset for indexing into that
char array, then copying back.
Another possible interpretation of the Standard is that the reinterpret_cast
pointer *does* point to an array. One way this interpretation could be
derived is from §1.8/5: "An object of trivially copyable or standard-layout
type (3.9) shall occupy contiguous bytes of storage.".
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <type_traits>
struct Meow
{
int x;
float y;
};
int main()
{
Meow meow;
static_assert(std::is_standard_layout<Meow>::value, "Meow isn't
standard-layout");
// Aliasing rules allow this (3.10/8)
unsigned char *p = reinterpret_cast<unsigned char *>(&meow);
// Meow is standard-layout, but is this technically undefined behavior?
p += offsetof(Meow, y);
float z = std::exp(1.0f);
std::memcpy(p, &z, sizeof(float));
std::printf("%f\n", meow.y);
return 0;
}
Addendum to my original email: For this to be undefined would be to
invalidate decades of existing programming practice.
Melissa
from the undefined-behavior list instead.
The C++ Standard permits you to use offsetof() on standard-layout classes,
but does it permit using that offset in pointer arithmetic with object
pointers that have been reinterpret_cast to [unsigned] char *?
The section on pointer arithmetic is predicated on "if the pointer object
points to an element of an array object" (§5.7/4), with undefined behavior
otherwise. It has a footnote stating that, "an object that is not an array
is considered to belong to a single-element array for this purpose". But
if you reinterpret_cast a pointer to a single object into a char pointer,
that's not a pointer to an array object.
Does this mean that doing pointer arithmetic on a reinterpret_cast char
pointer of a single object in order to reach other members is undefined
behavior even for standard-layout types? It seems to me that this was not
the intention of the Standard. Getting around this would require using
memcpy into a char array, only ever using the offset for indexing into that
char array, then copying back.
Another possible interpretation of the Standard is that the reinterpret_cast
pointer *does* point to an array. One way this interpretation could be
derived is from §1.8/5: "An object of trivially copyable or standard-layout
type (3.9) shall occupy contiguous bytes of storage.".
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <type_traits>
struct Meow
{
int x;
float y;
};
int main()
{
Meow meow;
static_assert(std::is_standard_layout<Meow>::value, "Meow isn't
standard-layout");
// Aliasing rules allow this (3.10/8)
unsigned char *p = reinterpret_cast<unsigned char *>(&meow);
// Meow is standard-layout, but is this technically undefined behavior?
p += offsetof(Meow, y);
float z = std::exp(1.0f);
std::memcpy(p, &z, sizeof(float));
std::printf("%f\n", meow.y);
return 0;
}
Addendum to my original email: For this to be undefined would be to
invalidate decades of existing programming practice.
Melissa
Received on 2015-05-18 21:55:28