LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-26-2006, 09:32 PM   #1
binarybob0001
Member
 
Registered: Dec 2004
Distribution: Debian Wheezy
Posts: 444

Rep: Reputation: 30
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.
 
Old 04-26-2006, 09:53 PM   #2
burninGpi
Member
 
Registered: Mar 2006
Location: Fort McMurray, Canada
Distribution: Gentoo ~amd64
Posts: 163

Rep: Reputation: 30
Please post the exact error message you got.
 
Old 04-27-2006, 12:50 AM   #3
binarybob0001
Member
 
Registered: Dec 2004
Distribution: Debian Wheezy
Posts: 444

Original Poster
Rep: Reputation: 30
/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?
 
Old 04-27-2006, 11:36 AM   #4
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
Pass a pointer; also try passing a reference. If the latter solution works, use that one.
 
Old 04-27-2006, 05:48 PM   #5
binarybob0001
Member
 
Registered: Dec 2004
Distribution: Debian Wheezy
Posts: 444

Original Poster
Rep: Reputation: 30
I have been reading on meta-programming. Is there any way to adjust the arguments using meta-programming?
 
Old 04-28-2006, 12:59 AM   #6
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
Why so complicated? Have you tried the references?
 
Old 04-28-2006, 04:52 AM   #7
binarybob0001
Member
 
Registered: Dec 2004
Distribution: Debian Wheezy
Posts: 444

Original Poster
Rep: Reputation: 30
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.
 
Old 04-28-2006, 09:54 AM   #8
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
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).
 
Old 04-28-2006, 06:34 PM   #9
binarybob0001
Member
 
Registered: Dec 2004
Distribution: Debian Wheezy
Posts: 444

Original Poster
Rep: Reputation: 30
Alright, looks like I made the right move.
 
Old 05-30-2006, 12:50 AM   #10
binarybob0001
Member
 
Registered: Dec 2004
Distribution: Debian Wheezy
Posts: 444

Original Poster
Rep: Reputation: 30
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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
5.4. GCC-3.4.3 - Pass 1 invalid host type problem thomas55 Linux From Scratch 9 05-01-2006 03:21 PM
What is the warning: passing arg 3 of `pthread_create' from incompatible pointer type wallwaters Linux - Software 3 06-01-2005 08:30 AM
When I type "su" I can't type the pass (suse 9.1) MagiNegi Linux - Newbie 6 08-08-2004 03:59 PM
Arch linux Help Cannot Type Pass bigbossandy Linux - Newbie 1 12-20-2003 10:11 AM
Wierd POD type error teval Programming 1 08-18-2003 06:32 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

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

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration