LinuxQuestions.org
Share your knowledge at the LQ Wiki.
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 01-06-2010, 01:20 PM   #1
ETCKerry
Member
 
Registered: Sep 2008
Posts: 37

Rep: Reputation: 15
g++ complains about function call not matching prototype


Hello,

I have a C++ project that I'm developing under Windows and (hopefully soon) Linux. Right now, it compiles and runs fine under Windows, but I'm having some trouble getting it to compile under Linux.

The error that I'm stuck on is this:
Code:
src/gui/iteration_class.cpp:387: error: no matching function for call to
âTHREAD_JOB::THREAD_JOB(THREAD_JOB::THREAD_COMMANDS, CAR*, CAR*, KINEMATICS::INPUTS&, KINEMATIC_OUTPUTS*&, wxString, int&)â
/home/Kerry/Projects/CarDesigner/common/include/vSolver/threads/thread_job_class.h:48: note: candidates are:
THREAD_JOB::THREAD_JOB(THREAD_JOB::THREAD_COMMANDS, const CAR*, CAR*, KINEMATICS::INPUTS&, KINEMATIC_OUTPUTS*, wxString&, int&)
I don't expect that the compiler would object to a CAR* instead of a const CAR*, or a wxString instead of a wxString&, so I'm guessing the real problem is the KINEMATIC_OUTPUTS*& instead of KINEMATIC_OUTPUTS*. I'm not sure why g++ think that argument is a reference to a pointer, though, because it's clearly not. Here's the code:
Code:
384  KINEMATIC_OUTPUTS *NewOutputs = new KINEMATIC_OUTPUTS;
385  THREAD_JOB Job(THREAD_JOB::COMMAND_THREAD_KINEMATICS_ITERATION, &AssociatedCars.GetObject(CurrentCar)->GetOriginalCar(),
386  &AssociatedCars.GetObject(CurrentCar)->GetWorkingCar(), KinematicInputs, NewOutputs,
387  AssociatedCars.GetObject(CurrentCar)->GetName(), Index);
388  MainFrame.AddJob(Job);
So it should just be a pointer to the outputs, like it wants, right? Or am I missing the real cause of the error? Like I said, this compiles under Windows without any problems (although I know the MS compilers will accept just about anything...). Any suggestions or ideas are welcome.

Thanks!

-Kerry
 
Old 01-06-2010, 02:17 PM   #2
ETCKerry
Member
 
Registered: Sep 2008
Posts: 37

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ETCKerry View Post
I'm guessing the real problem is the KINEMATIC_OUTPUTS*& instead of KINEMATIC_OUTPUTS*.
Turns out this was a bad guess - I commented out each argument one by one until the error went away. Turns out it was the wxString instead of a wxString& that the compiler doesn't like. Can anyone tell me why? I decided that since I'm passing it to a thread I should just pass a new instance anyway, but I'd still be curious to know why g++ complained.

EDIT: No, in the constructor for my THREAD_JOB class, I copy the reference to the name into a new instance of a wxString - so I like the approach that I had where I pass a reference to the constructor. Why isn't it working?

Thanks!

-Kerry

Last edited by ETCKerry; 01-06-2010 at 02:21 PM.
 
Old 01-06-2010, 02:22 PM   #3
alunduil
Member
 
Registered: Feb 2005
Location: San Antonio, TX
Distribution: Gentoo
Posts: 684

Rep: Reputation: 62
Pass by value and pass by reference require very different addressing schemes from within a called function. The pass by value gets a copied value in the activation record of the function when it gets called, but a reference is a redirection to the variable in the previous namespace. These two types simply shouldn't be coerced as the intent is different for each. Thus, the compiler throws an error to remain strict about its types.

Whenever possible make the compiler tell you errors; you can't go to wrong with that idea.

Regards,

Alunduil
 
Old 01-06-2010, 04:05 PM   #4
ETCKerry
Member
 
Registered: Sep 2008
Posts: 37

Original Poster
Rep: Reputation: 15
I'm sorry I still don't understand - maybe you can explain in more detail?

I have cases like this all throughout my code, but g++ doesn't complain for any of these:
Code:
void some_function(int& a)
{
   ...
}

void some_other_function(void)
{
    // call some function - it should get a reference to my_var
    int my_var(5);
    some_function(my_var);

    // even this compiles OK:
    some_function(83);
}
This is doing what I want - there is only one instance of the variable that is passed as an argument, and the called function modifies/uses the same variable via a reference. Am I not doing the same thing in my original post? This is where I'm confused.

Thanks for the speedy reply!

-Kerry
 
Old 01-06-2010, 04:19 PM   #5
alunduil
Member
 
Registered: Feb 2005
Location: San Antonio, TX
Distribution: Gentoo
Posts: 684

Rep: Reputation: 62
Perhaps I misread your original post. Could you show the prototype for the function in question as well?

Regards,

Alunduil
 
Old 01-06-2010, 05:42 PM   #6
ETCKerry
Member
 
Registered: Sep 2008
Posts: 37

Original Poster
Rep: Reputation: 15
Sure, here it is:
Code:
THREAD_JOB(THREAD_COMMANDS _Command, const CAR *OriginalCar,
		CAR *WorkingCar, KINEMATICS::INPUTS &_KinematicInputs,
		KINEMATIC_OUTPUTS *_Output, wxString &_Name, int &_Index);
Thanks!

-Kerry
 
Old 01-06-2010, 06:48 PM   #7
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
I assume AssociatedCars.GetObject(CurrentCar)->GetName() returns a wxString by value, making that value a temporary object in the context where GetName() was called.

You cannot pass a temporary object by non const ref. You can pass a temporary object by value. You can pass a temporary object by const&. You can assign a temporary object to a local variable and then pass that by non const ref.

I assume it is not practical to change getname() to return wxString& rather than wxString. If you could do that, it would fix the problem.

Probably it is practical to change THREAD_JOB::THREAD_JOB to take a wxString const& instead of wxString&. If so, that is the cleanest correction.

Failing either of those, I think you need to assign the returned wxString to a local wxString variable and then pass that local copy.

Quote:
Originally Posted by alunduil View Post
Pass by value and pass by reference require very different addressing schemes from within a called function. The pass by value gets a copied value in the activation record of the function when it gets called, but a reference is a redirection to the variable in the previous namespace. These two types simply shouldn't be coerced as the intent is different for each. Thus, the compiler throws an error to remain strict about its types.
A major part of that is incorrect:

The compiler can easily coerce the parameter when you provide a & or a const& and it needs to pass a value. Passing a value implies copying it and the compiler can copy from a & or const& as easily as from a local or temporary value.

The compiler can also easily coerce the parameter from a value, including a temporary or const value, into a const&.

But the compiler can't pass a & (non const) from a const value, nor from a temporary value.

I can't do a good job defending that detail in the C++ standard (I'm not sure I even agree with it). Part of the defense is that passing by non const ref implies the ability to modify the passed object, but a temporary value stops existing before the caller could see any such modification, so it sort of implies a logic error in the code.

Last edited by johnsfine; 01-07-2010 at 09:38 AM. Reason: minor typo
 
1 members found this post helpful.
Old 01-06-2010, 08:04 PM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by ETCKerry View Post
Code:
void some_function(int& a)
{
}

void some_other_function(void)
{
...
    // even this compiles OK:
    some_function(83);
}
Really? It doesn't work for me, I get
Code:
g++ -Wall -Wextra -g   -c -o struc.o struc.cc
struc.cc:24: warning: unused parameter 'a'
struc.cc: In function 'int main()':
struc.cc:35: error: invalid initialization of non-const reference of type 'int&' from a temporary of type 'int'
struc.cc:24: error: in passing argument 1 of 'void some_function(int&)'
make: *** [struc.o] Error 1
 
Old 01-06-2010, 08:45 PM   #9
ETCKerry
Member
 
Registered: Sep 2008
Posts: 37

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ntubski View Post
Really? It doesn't work for me, I get
Code:
g++ -Wall -Wextra -g   -c -o struc.o struc.cc
struc.cc:24: warning: unused parameter 'a'
struc.cc: In function 'int main()':
struc.cc:35: error: invalid initialization of non-const reference of type 'int&' from a temporary of type 'int'
struc.cc:24: error: in passing argument 1 of 'void some_function(int&)'
make: *** [struc.o] Error 1
Ah, yes, as do I. It appears I was wrong. Sorry about the confusion...

Quote:
Originally Posted by johnsfine View Post
...

Probably it is practical to change THREAD_JOB::THREAD_JOB to take a wxString const& instead of wxString&. If so, that is the cleanest correction.

...

I can't do a good job defending that detail in the C++ standard (I'm not sure I even agree with it). Part of the defense is that passing by non const ref implies the ability to modify the passed object, but a temporary value stops existing before the caller could see any such modification, so it sort of implies a logic error in the code.
Yes, I do think that's the cleanest solution. Thanks for the advice.

I guess I see some value in preventing passing a temporary object by reference, but I do think it would have been OK in this case, since I was only copying the reference into another object's class member - after that line was executed, the temporary object would have disappeared and it wouldn't have mattered. I'm surprised I haven't run into this before. Also curious that it compiles OK with MSVC++ 2008.

I appreciate all the help - thanks a lot!

-Kerry
 
  


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
function prototype charlitos Programming 9 04-14-2009 07:14 AM
How many prototype of function main in c? ypzhuang Programming 9 12-13-2008 07:53 AM
Compilation issue when Function is parameter in function call on LINUX sa20358 Linux - Software 2 07-24-2008 10:19 PM
Why 'extern' on function prototype Hko Programming 11 02-08-2006 04:50 PM
No Matching Function for Call ! vipinsharma Programming 2 07-05-2004 01:58 PM

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

All times are GMT -5. The time now is 06:56 PM.

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