Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
162 views
in Technique[技术] by (71.8m points)

c++ - Casting double array to a struct of doubles

Is it OK to cast a double array to a struct made of doubles?

struct A
{
   double x;
   double y;
   double z;
};

int main (int argc , char ** argv)
{
   double arr[3] = {1.0,2.0,3.0};
   A* a = static_cast<A*>(static_cast<void*>(arr));
   std::cout << a->x << " " << a->y << " " << a->z << "
";
}

This prints 1 2 3. But is it guaranteed to work every time with any compiler?

EDIT: According to

9.2.21: A pointer to a standard-layout struct object, suitably converted ? using a reinterpret_cast, points to its initial member (...) and vice versa.

if I replace my code with

struct A
{
  double & x() { return data[0]; }
  double & y() { return data[1]; }
  double & z() { return data[2]; }
private:
   double data[3];
};

int main (int, char **)
{
   double arr[3] = {1.0,2.0,3.0};
   A* a = reinterpret_cast<A*>(arr);
   std::cout << a->x() << " " << a->y() << " " << a->z() << "
";
}

then it is guaranteed to work. Correct? I understand that many people would not find this aesteticaly pleasing but there are advantages in working with a struct and not having to copy the input array data. I can define member functions in that struct to compute scalar and vector products, distances etc, that will make my code much easier to understand than if I work with arrays.

How about

int main (int, char **)
{
   double arr[6] = {1.0,2.0,3.0,4.0,5.0,6.0};
   A* a = reinterpret_cast<A*>(arr);
   std::cout << a[0].x() << " " << a[0].y() << " " << a[0].z() << "
";
   std::cout << a[1].x() << " " << a[1].y() << " " << a[1].z() << "
";
}

Is this also guaranteed to work or the compiler could put something AFTER the data members so that sizeof(A) > 3*sizeof(double)? And is there any portable way to prevent the compiler from doing so?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

No, it's not guaranteed.

The only thing prohibiting any compiler from inserting padding between x and y, or between y and z is common sense. There is no rule in any language standard that would disallow it.

Even if there is no padding, even if the representation of A is exactly the same as that of double[3], then it's still not valid. The language doesn't allow you to pretend one type is really another type. You're not even allowed to treat an instance of struct A { int i; }; as if it's a struct B { int i; };.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...