Jump to content
  • Advertisement
Sign in to follow this  
jonathanplumb

Function Pointer as argument nightmare ('&' requires l-value)

This topic is 3297 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

As the title states, I'm getting a "'&' requires l-value" error from the following code:
void InitTitleScreen();

void CSystem::PlayMovie(const char *filename, void *func(void))
{
	//TODO: Play movie ....

         //Call the end-function at the end of the movie
	*func();
}

void CSystem::GameLoop()
{
	switch (g_nGameState)
	{
	case STATE_INITIALIZATION:
		{
			PlayMovie("data\\Intro.mov", &InitTitleScreen());
		}
		break;
	}
}

void InitTitleScreen()
{
	MessageBox(NULL, L"TEST", L"Function pointers suck...", MB_OK);
}
The line that is giving me the error is:
PlayMovie("data\\Intro.mov", &InitTitleScreen());
I've read and re-read tutorials on function pointers ... and can easily do it in C#, but I want to do it in C++ and it is just a little frustrating. The way I'm seeing it, &InitTitleScreen() is the address of InitTitleScreen(), and I pass that to the PlayMovie function, which then calls the function through the parameter. I know that the "l-value" thing means that there is no value to assign from that, but that doesn't make sense, because shouldn't the function have an address? I also tried doing the following:
void *FuncPtr = &InitTitleScreen;
but that didn't help me much either ... just more errors...

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by jonathanplumb
The way I'm seeing it, &InitTitleScreen() is the address of InitTitleScreen()
InitTitleScreen() is not a function. InitTitleScreen() is a function call. InitTitleScreen is a function.

Share this post


Link to post
Share on other sites
if I change the call to
PlayMovie("data\\Intro.mov", &InitTitleScreen);

I get the following:

error C2664: 'CSystem::PlayMovie' : cannot convert parameter 2 from 'void (__cdecl *)(void)' to 'void *(__cdecl *)(void)'

Share this post


Link to post
Share on other sites
Quote:
Original post by Hodgman
Try replacing "void *func(void)" with "void (*func)(void)"
Actually, I'd recommend changing it to boost::function<void ()> - it's more readable (in my opinion) and it's more flexible, too!

Share this post


Link to post
Share on other sites
I'm not sure what that "boost::" is, but I fixed it by doing the following:

Changed PlayMovie() to the following:

void CSystem::PlayMovie(const char *filename, void (*func)(void))
{
//TODO: Play movie ....

(*func)();
}


Changed GameLoop() to the following:

void CSystem::GameLoop()
{
switch (g_nGameState)
{
case STATE_INITIALIZATION:
{
PlayMovie("data\\Intro.mov", &InitTitleScreen);
}
break;
}
}


and InitTitleScreen() didn't change. I think it was just a problem with my parenthesis not in the right place, making some odd typecasts or something.

Thanks for the help. Now off to learn OpenGL --

Share this post


Link to post
Share on other sites
Quote:
Original post by jonathanplumb
I'm not sure what that "boost::" is, but I fixed it by doing the following:


boost is a great big bunch of C++ awesomeness. It's got a whole bunch of neat stuff, including smart pointer classes, cross-platform threading/synchronization, cross-platform file system classes, serialization, networking, regular expressions, and more. Certainly worth checking out.

Codeka was talking about boost::function which lets you create function objects for use as callbacks. You can also combine it with boost::bind to create callbacks to class member functions, which is really neat.

Share this post


Link to post
Share on other sites
I know I'm late, but I bet that the reason you got the error is because you typed &InitScreen instead of InitScreen (when parenthesis are not used it becomes a pointer to the function).

Share this post


Link to post
Share on other sites
Quote:
Original post by jonathanplumb

void CSystem::PlayMovie(const char *filename, void (*func)(void))
{
//TODO: Play movie ....

(*func)();
}


Since you cannot pass functions as arguments (only function pointers), the asterisk in parameters is optional.

It is also optional when you call a function through a function pointer -- in fact, it is even more natural without the asterisk, because calling "normal functions" does a silent conversion to a function pointer first before calling the function anyway -- but that detail is not so important :)

void CSystem::PlayMovie(const char *filename, void func())
{
//TODO: Play movie ....

func();
}

This SHOULD work, but I haven't tested it. Please confirm.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!