LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   warning: cannot pass objects of non-POD type (http://www.linuxquestions.org/questions/programming-9/warning-cannot-pass-objects-of-non-pod-type-439192/)

binarybob0001 04-26-2006 09:32 PM

warning: cannot pass objects of non-POD type
 
What does is a non-POD type? I get this error compiling the following code.

Code:

template<class BaseType, class X>
class VectorND : public PointND<BaseType, X>
{
public:
 VectorND CrossProduct(VectorND p ...)
 {
  VectorND ret;
  int temp[N*(N-1)];
  va_list ap;
  va_start (ap, p);
  for(int v = 0; v<N; v++) //put this vector in the matrix
  temp[v] = x[v];
  for(int v = 0; v<N; v++) //put first vector passed in matrix
  temp[v+N] = p.x[v];
  for(int u = 2; u < N-1; u++) //put the rest of the vectors in the matrix
  {
  p = va_arg(ap, VectorND);
  for(int v = 0; v<N; v++)
    temp[v+u*N] = p.x[v];
  }
 
  for(int v = 0; v< N*(N-1); v++)
  cout << temp[v] << " ";
  cout << endl;
 
  va_end(ap);
  return ret;
 }
}

int main(int argc, char *argv[])
{
 VectorND<int, int[4]> a(1, 2, 3, 4);
 VectorND<int, int[4]> b(5, 6, 7, 8);
 VectorND<int, int[4]> c(9, 10, 11, 12);
 c = c.CrossProduct(a, b);
 return EXIT_SUCCESS;
}

How do I fix this problem? Thanks.

burninGpi 04-26-2006 09:53 PM

Please post the exact error message you got.

binarybob0001 04-27-2006 12:50 AM

/home/bobby/test/src/test.cpp:258: warning: cannot pass objects of non-POD type `class VectorND<int, int[4]>' through `...'; call will abort at runtime

That's the message in its entirety. I looked up what POD means. It means Plain Old Data. Apparently classes are not guaranteed to be passed evenly onto the stack or something. So, va_arg is not guaranteed to work hence the segmentation fault error. Is there any way around this?

addy86 04-27-2006 11:36 AM

Pass a pointer; also try passing a reference. If the latter solution works, use that one.

binarybob0001 04-27-2006 05:48 PM

I have been reading on meta-programming. Is there any way to adjust the arguments using meta-programming?

addy86 04-28-2006 12:59 AM

Why so complicated? Have you tried the references?

binarybob0001 04-28-2006 04:52 AM

Yes, references are instant death. Seems like I'm forced to use pointers which is inconsistent with the rest of the class design. For example, on initialization, I passed data to my vectors using this:

Code:

template<class BaseType, class X>
class VectorND : public PointND<BaseType, X>
{
public:
 explicit VectorND();
 explicit VectorND(BaseType sx ...);
}

This looked nice in that when I initialized a vector, I had a comma separated list.

Code:

int main()
{
 VectorND<int, int[3]> v(1, 2, 3); //make a 3d vector
 return 0;
}

I like the way that looks. It would be nice to do a simular thing with the cross product.

Code:

int main()
{
 VectorND<int, int[4]> v1(1, 1, 1, 0);
 VectorND<int, int[4]> v2(1, -1, -1, 0);
 VectorND<int, int[4]> v3(1, -1, 1, 0);
 VectorND<int, int[4]> v4;
 v4 = v1.CrossProduct(v2, v3); //Get cross product between v1, v2, v3
 return 0;
}

There are several problems with this design. Corrupting the stack is far too easy. It would be easy to neglect a single number and create a segmentation fault. Hence, it would be nice to get away from variatable functions all together. I decided to change my design recently to use an array as an initializer. This is not a pretty solution, but it forces you to pass the right number of parameters. If you guys have any idea of how I can make this pretty and safe, please let me know. Thanks for all the help so far.

addy86 04-28-2006 09:54 AM

Is there an upper bound to the number of arguments? If yes, you could just use default values (I don't know whether that is possible with non-POD types); if the caller passes too many arguments, your algorithm can simply ignore them.
However, in my opinion, this solution is much uglier than passing an array (respectively a std::vector).

binarybob0001 04-28-2006 06:34 PM

Alright, looks like I made the right move.

binarybob0001 05-30-2006 12:50 AM

It has been a while since I last posted this question, but I did manage to solve the problem entirely. If you want the answer, read on. I'll be using sudo code since I don't want to spend a lot of time trying to simplify complex code. Basically, have the constructor set the vector to zero. Second, overload the assignment operator to take in a value (such as an integer to the first component) and then have the operator return an intializer object.

Code:

InitObj operator=(const int val)
{
 InitObj ret(begin(), val); //begin() refers to beginning of the array that represents the vector
 return ret;
}

Finally, overload the initializer object's comma operator to take in a value.
Code:

InitObj operator,(const int val)
{
 *component = val; //assign a value to the current component
 ++component; //get ready for the next component
}

After doing this it is now possible to write.
Vector<int, 3> v;
//calls the vectors operator= and the uses the initializers operator, to initialize the rest
v = 1, 2, 3;

This is neet and compact. Initializing the vectors may be a little slower since the constructor can't be used directly, but this is a nice solution to a hard problem.


All times are GMT -5. The time now is 05:51 AM.