g++ complains about function call not matching prototype
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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:
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.
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?
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.
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.
THREAD_JOB(THREAD_COMMANDS _Command, const CAR *OriginalCar,
CAR *WorkingCar, KINEMATICS::INPUTS &_KinematicInputs,
KINEMATIC_OUTPUTS *_Output, wxString &_Name, int &_Index);
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
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
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
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
...
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.